opam-cross-windows icon indicating copy to clipboard operation
opam-cross-windows copied to clipboard

flexdll.h not found error when running "ocaml install ocaml-windows"

Open lonelyfloat opened this issue 2 years ago • 1 comments

Steps to reproduce (from fresh Manjaro install (also occured on Ubuntu)):

Install mingw64: sudo pacman -S mingw-w64-gcc Install opam: sudo pacman -S opam (or the curl command on the ocaml website, tried both) Initialize opam normally with the steps here: https://ocaml.org/docs/up-and-running Then, follow the exact steps in the README.md in this repository.

opam install ocaml-windows fails with this error:

#=== ERROR while compiling ocaml-windows64.4.14.0 =============================#
# context     2.1.2 | linux/x86_64 | ocaml.4.14.0 | git+https://github.com/ocaml-cross/opam-cross-windows.git
# path        ~/.opam/default/.opam-switch/build/ocaml-windows64.4.14.0
# command     ~/.opam/opam-init/hooks/sandbox.sh build /bin/sh ./build.sh x86_64-w64-mingw32
# exit-code   2
# env-file    ~/.opam/log/ocaml-windows64-26776-f3eddf.env
# output-file ~/.opam/log/ocaml-windows64-26776-f3eddf.out
### output ###
# [...]
# checking for flexdll.h... no
# configure: error: flexdll.h is required for native Win32
# make: Entering directory '/home/lonelyfloat/.opam/default/.opam-switch/build/ocaml-windows64.4.14.0/runtime'
# ../Makefile.config_if_required:27: ../Makefile.build_config: No such file or directory
# make: *** No rule to make target '../Makefile.build_config'.  Stop.
# make: Leaving directory '/home/lonelyfloat/.opam/default/.opam-switch/build/ocaml-windows64.4.14.0/runtime'
# make -C runtime sak
# make[1]: Entering directory '/home/lonelyfloat/.opam/default/.opam-switch/build/ocaml-windows64.4.14.0/runtime'
# ../Makefile.config_if_required:27: ../Makefile.build_config: No such file or directory
# make[1]: *** No rule to make target '../Makefile.build_config'.  Stop.
# make[1]: Leaving directory '/home/lonelyfloat/.opam/default/.opam-switch/build/ocaml-windows64.4.14.0/runtime'
# make: *** [Makefile:785: runtime/sak] Error 2

I did the exact same steps on Ubuntu and Manjaro (arch based) and got the same error. Is there some external dependency that I'm missing?

lonelyfloat avatar Jul 31 '22 03:07 lonelyfloat

I have the same problem on Debian 11, with OCaml 4.14.

murmour avatar Sep 08 '22 16:09 murmour

I have the same problem on Manjaro, with OCaml 4.14.0

muqiuhan avatar Dec 15 '22 13:12 muqiuhan

The flexdll.h file should be installed by flexdll-windows. Do y'all have it installed?

$ find ~/.opam/ -name flexdll.h
/home/opam/.opam/4.12.0/lib/flexdll-windows/flexdll.h

toots avatar Jan 10 '23 20:01 toots

I have it installed and it still doesn't work.

lonelyfloat avatar Jan 11 '23 23:01 lonelyfloat

Hmm indeed I can confirm that the check for flexdll.h fails but allows the ./configure script to keep running when installing via opam inside the mxe cross compilation image:

- checking whether host executables can be run in the build...
- no
- checking whether #! works in shell scripts... yes
- checking for flexdll sources... checking for flexlink... no
- checking flexdll.h usability... no
- checking flexdll.h presence...
- no
- checking for flexdll.h... no
- checking for a BSD-compatible install... /usr/bin/install -c
- checking for cos in -lm... yes
- checking math.h usability...
- yes
- checking math.h presence... yes
- checking for math.h... yes

While it fails outside of it, including when running it manually inside the same image:

checking whether #! works in shell scripts... yes
checking for flexdll sources... no
checking for flexlink... no
checking flexdll.h usability... no
checking flexdll.h presence... no
checking for flexdll.h... no
configure: error: flexdll.h is required for native Win32

Investigating the difference...

toots avatar Jan 12 '23 05:01 toots

It looks like the difference is because of the host name: the docker image build uses x86_64-w64-mingw32.static which breaks some of the windows-specific tests in ./configure compared to x86_64-w64-mingw32... 😬

toots avatar Jan 12 '23 05:01 toots

Romain Beauxis (2023/01/11 21:34 -0800):

It looks like the difference is because of the host name: the docker image build uses x86_64-w64-mingw32.static which breaks some of the windows-specific tests in ./configure... 😬

Yeah that hostname canprobably not be normalized to what ./configure knows. Can the script be called with explicit --build and --host options? It's indeed important to knowthat ./configure expects --build to be set explicitly when --host is so it would be best and safest to set both.

shindere avatar Jan 12 '23 06:01 shindere

Unfortunately, it also breaks when ran as:

./configure --build=x86_64-linux-gnu --host=x86_64-w64-mingw32

toots avatar Jan 12 '23 12:01 toots

With the same error you mean?

What do I need to install to reproduce?

shindere avatar Jan 12 '23 13:01 shindere

It is an issue related to cross-compiling the ocaml compiler for mingw-w64 on a linux host.

Steps to reproduce on a clean debian distribution (for instance a docker image) with x86_64 architecture:

  • Install mingw-w64
  • Initialize opam with OCaml 4.14.0
  • Add the ocaml-cross repository:
opam repository add windows https://github.com/ocaml-cross/opam-cross-windows.git
  • Install ocaml-windows

The error relates to the configure script not being able to find flexdll.h. The header and a cross-compiled binary are installed via the flexdll-windows package. However, when pointed directly to its installation location, both binary detection (via $PATH) and header (via $CFLAGS) fail.

Header is accepted b/c the configure script eventually accepts the compiler over the linker but the binary is considered not runnable. The configure script should either know how to run it using wine or simply skip trying to run it when build and host are not the same.

This went unnoticed b/c the automated build images for this are using a different host, as explained above, x86_64-w64-mingw32.static. This non-standard name confuses the configure which turns off requirement for flexdll and makes it pass.

I haven't dived into the build process in a while but, essentially, we do some bootstrapping based off the configure script output and then provide our own Makefile.config and proceed with the final build:

./configure --host=$1

make -C runtime primitives sak SAK_CC=cc SAK_LINK='cc -o $(1) $(2)'

cp `which ocamlrun` runtime/ocamlrun
cp -f Makefile.cross Makefile.config
cp -f s-nt.h runtime/caml/s.h
cp -f m-nt.h runtime/caml/m.h

if grep "WITH_SPACETIME=true" Makefile.config >/dev/null 2>/dev/null; then
  echo "#define WITH_SPACETIME" >> runtime/caml/m.h
  echo "#define WITH_PROFINFO" >> runtime/caml/m.h
fi

make world opt \
  compilerlibs/ocamlcommon.cmxa compilerlibs/ocamlbytecomp.cmxa \
  compilerlibs/ocamloptcomp.cmxa driver/main.cmx driver/optmain.cmx \
  PROGRAMS= \
  OCAMLRUN=ocamlrun \
  NEW_OCAMLRUN=ocamlrun

Any suggestion as to how to improve this would be gladly welcome!

toots avatar Jan 12 '23 13:01 toots

Working on this. It looks like it should be possible to cross-compile ocaml with the existing configure/makefile system but I haven't found the right magical invocation yet.

toots avatar Feb 10 '23 19:02 toots

Happy to report that this is now fixed. I was also able to find a way to build the cross-compiler using the upstream configure/make system, which should make it even more robust and hopefully easy to update to future versions.

toots avatar Feb 12 '23 22:02 toots

The issue with host triplet has been fixed upstream. There are a couple more small issues related to flexlink that I might push upstream at some point as well.

toots avatar Feb 12 '23 22:02 toots