Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross compiler, take 3 #15

Closed
wants to merge 17 commits into from
Closed

Cross compiler, take 3 #15

wants to merge 17 commits into from

Conversation

shym
Copy link
Owner

@shym shym commented Oct 22, 2024

No description provided.

shym added 3 commits October 4, 2024 15:19
The `runtime` directory must be `-I`ncluded only since PR#12896 and only
in ocamltest.
When building an OCaml cross compiler, two OCaml compilers are really
involved, where the non-cross compiler is used to build the cross one.
Most cross-compiler projects do that by overriding variables such as
`CAMLOPT` to point to the non-cross compiler during the build of the
cross compilers. In these use cases, adding the explicit `-I runtime`
makes them generate the cross compilers linking in the cross runtime
(which naturally fails) instead of the build/host runtime that the
non-cross compiler would use without `-I runtime`. To re-enable those
use cases, this patch moves the addition only on `ocamltest/%` targets.
Recall that the only currently officially supported configurations are
when `build` ~ `host` = `target`, where '~' means that the code
generated for `host` runs on `build` even when they differ (such as when
`build` is `x86_64-pc-cygwin` and `host` is `x86_64-pc-windows` (MSVC)
or `x86_64-w64-mingw32`).

Still, many projects use OCaml cross compilers. All those projects
generate a cross compiler by assuming a non-cross OCaml compiler is
available in `PATH` (where non-cross means generating code that will run
on `host`). For the cross compiler, a C compiler and binutils for
`target` are necessary to build the target runtime. (Note that the
non-cross compiler will link its own (`build`/`host`) runtime into the
generated `.opt` cross compilers rather than the just-compiled target
runtime.)

In that setup the runtime that will be compiled to create a cross
compiler will run only on the `target` so this commit:

- sets `cross_compiling` by comparing `build` to `target` (rather than
  to `host`), as this variable will be used later,
- uses `target` to set up the tool prefix,
- temporarily assigns `host*` values to `target*` values during the
  libtool configuration, as this detects a `build` to `host` toolchain.

Note that all these changes are transparent when `host` = `target`.
shym added 12 commits October 24, 2024 09:54
As the C toolchain used being configured is generating code for
`target`, use `target` in every test that is done according to the
toolchain.

Note that all these changes are transparent when `host` = `target`.
Import `ax_prog_cc_for_build` from the Autoconf Macro Archive to detect
the C toolchain for the build machine when (and only when) we are
generating a cross compiler, namely when code generated for the target
doesn't run on the build machine
Move the configuration of `SAK_*` variables in `configure` to set them
using the build C toolchain to compile and link `sak` when generating a
cross compiler
This assumes that `sak` can be built with the default
automatically-detected flags when building a cross compiler
When building a cross compiler using an already built non-cross
compiler, check that they are of the same version as a sanity check, as
the cross compiler will be linked using the OCaml code in the source
tree and the C runtime from the non-cross compiler
Add a `--with-target-libdir` option to `configure` and assign a Makefile
`TARGET_LIBDIR` variable with it
Use the value of `LIBDIR` by default for this new variable
Use `TARGET_LIBDIR` to define the `OCAML_STDLIB_DIR` macro used by the
runtime

When building a cross compiler, the OCaml standard library has no reason
to be found at the same paths on the host and on the target. This allows
users to provide a path that is meaningful to look for libraries to link
dynamically on the target.
On Unix platforms, make sure it is possible to have a `flexlink`
executable in `PATH` (which is useful for instance when using a cross
compiler to Windows), and still be able to configure and build a
non-cross compiler
Add a new `Makefile.cross` that gets enabled when building a cross
compiler, aka when host is different from target
Define two new (phony) targets:
- crossopt, to build the cross compilers to the native target (and what
  is required for such cross compilers to work)
- installcross, to install the cross compilers
Add a rule to build flexdll in the cross-compiler setting, namely
building flexdll on Unix, by driving its `Makefile` so that Windows
resources are not built and only the .opt version is really built (and
copied to the byte binary directory nevertheless)
Use the `-o` flag to tell `make` to never try to rebuild `flexlink` (as
it would otherwise, according to the dependencies in the main
`Makefile`)
When building an OCaml cross-compiler Windows to Unix, `sak` gets a
Windows string (of UTF-16 `wchar_t`s) and must produce a Unix string (of
UTF-8 `char`s). And vice versa when building a cross-compiler Unix to
Windows. To make this possible, this commit splits the
`encode-C-literal` command into two commands with specific encodings of
the result: `encode-C-utf8-literal` and `encode-C-utf16-literal`.

Instead of pulling in a library (and the problems of linking with it)
for the task, this commit adds the specific and simple UTF-* encoders
and decoders that are needed and uses them only when building a
cross-compiler (the result is unchanged in non-cross-compiler settings).

In the cross-compiler UTF-8 case, the non-printable characters are
encoded to get a safer generated code.
Define `Config.target_os_type` so that:

- the `%ostype_*` primitives correspond to the target OS type rather
  than the host OS one,
- the default executable name is the expected default of the target
  platform.
This CI workflow is not intended to be merged on the main branch as is.
Its purpose is to help review the cross compiler.

If it is deemed interesting to keep it for special cases (to run the
test from time to time, rather less regularly), it could be triggered on
explicit `workflow_dispatch` or on a specific label. In that case, it
might make sense to amend it, in particular the tests for the new cases
in `sak` could be dropped.
@shym shym closed this Nov 5, 2024
@shym shym deleted the ocross-android branch January 6, 2025 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant