Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/syntax.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ jobs:
syntax-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v6
- name: Check Markdown links
uses: gaurav-nelson/github-action-markdown-link-check@v1
uses: gaurav-nelson/github-action-markdown-link-check@3c3b66f1f7d0900e37b71eca45b63ea9eedfce31 # v1.0.17
with:
use-verbose-mode: 'yes'
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # v2.0.0
502 changes: 163 additions & 339 deletions .github/workflows/test.yml

Large diffs are not rendered by default.

34 changes: 33 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
## 3.3.0
## 4.0.0

* `V4` gains full musl parity on Linux: new ABIs `Linux_x86_musl` and
`Linux_arm64_musl` join `Linux_x86_64_musl`. The `<features.h>` /
`__GLIBC__` test now covers the `__i386__` and `__aarch64__` branches of
the C header (new macros `DKML_ABI_linux_x86_musl` and
`DKML_ABI_linux_arm64_musl`).
* `V1`-`V3` report the new musl ABIs under their glibc names (`Linux_x86`,
`Linux_arm64`), matching the existing `Linux_x86_64_musl` -> `Linux_x86_64`
behavior. In `V1`, an x86 musl host gets the pre-existing `Result.error`
because `V1` never had `Linux_x86`.
* BREAKING (relative to the unpublished 3.3.0 git tag): the `V4.t_abi`
constructor list stays alphabetical, so the insertions change the ranks of
later constructors. Rebuild anything that marshalled `V4.t_abi` values.
3.3.0 was tagged but never published to opam; use 4.0.0 instead.
* `C_conf.load ()` now uses `V4` (was `V3`): on musl hosts the ABI-specific
environment variable suffix is now e.g. `DEFAULT_LINUX_X86_64_MUSL` instead
of `DEFAULT_LINUX_X86_64`. glibc, Windows, and macOS hosts are unchanged.
* Versioning policy restored: interface module `V<n>` ships in major version
`n` (`V4` <-> 4.0.0, as `V3` <-> 3.0.0 and `V2` <-> 2.0.0).
* Known gap: the Linux arm32 ABIs (`linux_arm32v6`, `linux_arm32v7`) have no
musl variants yet.
* CI: GitHub Actions re-enabled and every workflow brought onto the
repository's curated Actions allowlist (third-party actions SHA-pinned).
The `Tests` workflow now also covers musl: a C-header probe on Alpine
(musl) and Debian (glibc) across x86_64, x86 and arm64, and the full
dune-configurator path on a real musl host, alongside the BSD guests
(upgraded `cross-platform-actions`) and the Windows/macOS/Linux matrix on
`ocaml/setup-ocaml` (replacing the former DkML MSVC/MSYS2 + manylinux
reusable-workflow matrix, whose actions are not allowlisted). `syntax.yml`
upgraded to pinned `markdown-link-check` and `action-shellcheck`.

## 3.3.0 (git tag only; never published to opam — superseded by 4.0.0)

* Add `V4` with the new ABI `Linux_x86_64_musl`: a Linux x86_64 host whose C
compiler targets a non-glibc libc (musl). Detection pulls in `<features.h>`
Expand Down
8 changes: 7 additions & 1 deletion CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ If you would like to add a new ABI, you will need to:
* Add the ABI introspection test to the C header at [src/config/dkml_compiler_probe.h](src/config/dkml_compiler_probe.h).
* Create a new versioned module (ex. `module V123`) of the ABI enumeration in
[src/config/discover.ml](src/config/discover.ml). See how `module V2` extends `module V1` in a backwards-compatible way.
* Update the `(version xxx)` in [dune-project](dune-project)
* Extend `adjust_pre_v<n>_abi` in [src/config/discover.ml](src/config/discover.ml)
so the older modules degrade the new ABI: to the closest pre-existing ABI if
older consumers always saw that value on such hosts (like the musl ABIs), or
to `Result.error` if the ABI is genuinely new to them (like the BSDs).
* Update the `(version xxx)` in [dune-project](dune-project). A new
`module V<n>` must ship as major version `n.0.0`: the interface module
version matches the opam major version.

Before submitting your PR make sure you have:
1. Run `dune build`
Expand Down
40 changes: 26 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,11 @@ module V4 :
| Linux_arm32v6
| Linux_arm32v7
| Linux_arm64
| Linux_arm64_musl
| Linux_x86
| Linux_x86_64
| Linux_x86_64_musl
| Linux_x86_musl
| NetBSD_x86_64
| OpenBSD_x86_64
| Windows_arm32
Expand Down Expand Up @@ -350,9 +352,24 @@ The header file will be available as the following expressions:
# else
# define DKML_OS_NAME "Linux"
# define DKML_OS_Linux
/* musl does not define an identifying macro. Pull in <features.h>
(glibc and uclibc define __GLIBC__ there; musl defines nothing)
and treat a hosted Linux without __GLIBC__ as musl. */
# if defined(__has_include)
# if __has_include(<features.h>)
# include <features.h>
# endif
# else
# include <features.h>
# endif
# if __aarch64__
# define DKML_ABI "linux_arm64"
# define DKML_ABI_linux_arm64
# if defined(__GLIBC__)
# define DKML_ABI "linux_arm64"
# define DKML_ABI_linux_arm64
# else
# define DKML_ABI "linux_arm64_musl"
# define DKML_ABI_linux_arm64_musl
# endif /* __GLIBC__ */
# elif __arm__
# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
# define DKML_ABI "linux_arm32v6"
Expand All @@ -362,16 +379,6 @@ The header file will be available as the following expressions:
# define DKML_ABI_linux_arm32v7
# endif /* __ARM_ARCH_6__ || ..., __ARM_ARCH_7__ || ... */
# elif __x86_64__
/* musl does not define an identifying macro. Pull in <features.h>
(glibc and uclibc define __GLIBC__ there; musl defines nothing)
and treat a hosted Linux x86_64 without __GLIBC__ as musl. */
# if defined(__has_include)
# if __has_include(<features.h>)
# include <features.h>
# endif
# else
# include <features.h>
# endif
# if defined(__GLIBC__)
# define DKML_ABI "linux_x86_64"
# define DKML_ABI_linux_x86_64
Expand All @@ -380,8 +387,13 @@ The header file will be available as the following expressions:
# define DKML_ABI_linux_x86_64_musl
# endif /* __GLIBC__ */
# elif __i386__
# define DKML_ABI "linux_x86"
# define DKML_ABI_linux_x86
# if defined(__GLIBC__)
# define DKML_ABI "linux_x86"
# define DKML_ABI_linux_x86
# else
# define DKML_ABI "linux_x86_musl"
# define DKML_ABI_linux_x86_musl
# endif /* __GLIBC__ */
# elif defined(__ppc64__) || defined(__PPC64__)
# define DKML_ABI "linux_ppc64"
# define DKML_ABI_linux_ppc64
Expand Down
8 changes: 4 additions & 4 deletions dkml-c-probe.opam
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
version: "3.3.0"
version: "4.0.0"
synopsis:
"Cross-compiler friendly ABI and library discovery for OCaml's native C compilers"
description: """
Expand Down Expand Up @@ -32,8 +32,8 @@ build: [
["dune" "build" "-p" name "-j" jobs "@doc"] {with-doc}
]
# dkml-c-probe has strong backwards-compatibility.
# Any 3.x minor version is maintained for the latest patch version.
# Any 3.x or 4.x minor version is maintained for the latest patch version.
# Please upgrade if there is a patch version for a minor release;
# the patch generally means there was an important bug fix.
# Also the latest version is maintained, in case it gets to 4.x.x.
x-maintenance-intent: ["latest" "3.(any).(latest)"]
# Also the latest version is maintained.
x-maintenance-intent: ["latest" "4.(any).(latest)" "3.(any).(latest)"]
6 changes: 3 additions & 3 deletions dkml-c-probe.opam.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ build: [
["dune" "build" "-p" name "-j" jobs "@doc"] {with-doc}
]
# dkml-c-probe has strong backwards-compatibility.
# Any 3.x minor version is maintained for the latest patch version.
# Any 3.x or 4.x minor version is maintained for the latest patch version.
# Please upgrade if there is a patch version for a minor release;
# the patch generally means there was an important bug fix.
# Also the latest version is maintained, in case it gets to 4.x.x.
x-maintenance-intent: ["latest" "3.(any).(latest)"]
# Also the latest version is maintained.
x-maintenance-intent: ["latest" "4.(any).(latest)" "3.(any).(latest)"]
2 changes: 1 addition & 1 deletion dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(name dkml-c-probe)

(version 3.3.0)
(version 4.0.0)

(using mdx 0.1)

Expand Down
2 changes: 1 addition & 1 deletion src/c_conf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ let load_from_dune_context_name ?(getenv = default_env_getter) ctxname =
else create_error ()

let load ?(getenv = default_env_getter) () =
let abi_name_res = C_abi.V3.get_abi_name () in
let abi_name_res = C_abi.V4.get_abi_name () in
match abi_name_res with
| Ok abi_name -> load_from_findlib_toolchain ~getenv (Some abi_name)
| Error msg -> Error msg
Expand Down
42 changes: 20 additions & 22 deletions src/config/discover.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,6 @@
open Configurator.V1
open Flags

type t_abi =
| Android_arm64v8a
| Android_arm32v7a
| Android_x86
| Android_x86_64
| Darwin_arm64
| Darwin_x86_64
| Linux_arm64
| Linux_arm32v6
| Linux_arm32v7
| Linux_x86_64
| Linux_x86
| Windows_x86_64
| Windows_x86

type osinfo = {
ostypename : (string, string) result;
osname: (string, string) result;
Expand Down Expand Up @@ -95,6 +80,8 @@ let get_osinfo t =
(Result.ok "Unknown_unknown")
| [ (_, String ("linux_arm64")) ] ->
(Result.ok "Linux_arm64")
| [ (_, String ("linux_arm64_musl")) ] ->
(Result.ok "Linux_arm64_musl")
| [ (_, String ("linux_arm32v6")) ] ->
(Result.ok "Linux_arm32v6")
| [ (_, String ("linux_arm32v7")) ] ->
Expand All @@ -104,6 +91,8 @@ let get_osinfo t =
| [ (_, String ("linux_x86_64_musl")) ] ->
(Result.ok "Linux_x86_64_musl")
| [ (_, String ("linux_x86")) ] -> (Result.ok "Linux_x86")
| [ (_, String ("linux_x86_musl")) ] ->
(Result.ok "Linux_x86_musl")
| [ (_, String "linux_ppc64") ] ->
(Result.ok "Unknown_unknown")
| [ (_, String "linux_s390x") ] ->
Expand Down Expand Up @@ -144,15 +133,21 @@ let result_to_quoted_string = function
| Result.Error e -> "Result.error (\"" ^ String.escaped e ^ "\")"

(* Unlike the pre-V2/pre-V3 adjusters which downgrade newer ABIs to
Result.error, the musl ABI degrades to plain Linux_x86_64 in V1-V3. A musl
host is a Linux x86_64 host, and V1-V3 consumers compiled before musl
detection existed always saw Linux_x86_64 on musl (the probe could not tell
the difference), so reporting Linux_x86_64 preserves their behavior instead
of turning working consumers into runtime errors. *)
Result.error, the musl ABIs degrade to their glibc counterparts in V1-V3.
A musl host is still the same Linux machine architecture, and V1-V3
consumers compiled before musl detection existed always saw the glibc name
there (the probe could not tell the difference), so keeping the glibc name
preserves their behavior instead of turning working consumers into runtime
errors. In V1 the degraded Linux_x86 then hits adjust_pre_v2_abi's
Result.error, since V1 never had Linux_x86. *)
let adjust_pre_v4_abi ~abitypename ~abiname =
match (abitypename, abiname) with
| Result.Ok "Linux_arm64_musl", _ | _, Result.Ok "linux_arm64_musl" ->
(Result.ok "Linux_arm64", Result.ok "linux_arm64")
| Result.Ok "Linux_x86_64_musl", _ | _, Result.Ok "linux_x86_64_musl" ->
(Result.ok "Linux_x86_64", Result.ok "linux_x86_64")
| Result.Ok "Linux_x86_musl", _ | _, Result.Ok "linux_x86_musl" ->
(Result.ok "Linux_x86", Result.ok "linux_x86")
| Result.Ok tn, Result.Ok n -> (Result.ok tn, Result.ok n)
| Result.Error e, _ | _, Result.Error e -> (Result.error e, Result.error e)

Expand Down Expand Up @@ -365,8 +360,9 @@ let () =

(* V4.

Adds Linux_x86_64_musl: a Linux x86_64 host whose C compiler targets
a non-glibc libc (musl). V1-V3 report such a host as Linux_x86_64
Adds the musl ABIs Linux_arm64_musl, Linux_x86_64_musl and
Linux_x86_musl: Linux hosts whose C compiler targets a non-glibc
libc (musl). V1-V3 report such hosts under the glibc ABI names
(see adjust_pre_v4_abi). *)
let lines =
lines
Expand Down Expand Up @@ -398,9 +394,11 @@ let () =
| Linux_arm32v6
| Linux_arm32v7
| Linux_arm64
| Linux_arm64_musl
| Linux_x86
| Linux_x86_64
| Linux_x86_64_musl
| Linux_x86_musl
| NetBSD_x86_64
| OpenBSD_x86_64
| Windows_arm32
Expand Down
38 changes: 24 additions & 14 deletions src/config/dkml_compiler_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,24 @@
# else
# define DKML_OS_NAME "Linux"
# define DKML_OS_Linux
/* musl does not define an identifying macro. Pull in <features.h>
(glibc and uclibc define __GLIBC__ there; musl defines nothing)
and treat a hosted Linux without __GLIBC__ as musl. */
# if defined(__has_include)
# if __has_include(<features.h>)
# include <features.h>
# endif
# else
# include <features.h>
# endif
# if __aarch64__
# define DKML_ABI "linux_arm64"
# define DKML_ABI_linux_arm64
# if defined(__GLIBC__)
# define DKML_ABI "linux_arm64"
# define DKML_ABI_linux_arm64
# else
# define DKML_ABI "linux_arm64_musl"
# define DKML_ABI_linux_arm64_musl
# endif /* __GLIBC__ */
# elif __arm__
# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
# define DKML_ABI "linux_arm32v6"
Expand All @@ -106,16 +121,6 @@
# define DKML_ABI_linux_arm32v7
# endif /* __ARM_ARCH_6__ || ..., __ARM_ARCH_7__ || ... */
# elif __x86_64__
/* musl does not define an identifying macro. Pull in <features.h>
(glibc and uclibc define __GLIBC__ there; musl defines nothing)
and treat a hosted Linux x86_64 without __GLIBC__ as musl. */
# if defined(__has_include)
# if __has_include(<features.h>)
# include <features.h>
# endif
# else
# include <features.h>
# endif
# if defined(__GLIBC__)
# define DKML_ABI "linux_x86_64"
# define DKML_ABI_linux_x86_64
Expand All @@ -124,8 +129,13 @@
# define DKML_ABI_linux_x86_64_musl
# endif /* __GLIBC__ */
# elif __i386__
# define DKML_ABI "linux_x86"
# define DKML_ABI_linux_x86
# if defined(__GLIBC__)
# define DKML_ABI "linux_x86"
# define DKML_ABI_linux_x86
# else
# define DKML_ABI "linux_x86_musl"
# define DKML_ABI_linux_x86_musl
# endif /* __GLIBC__ */
# elif defined(__ppc64__) || defined(__PPC64__)
# define DKML_ABI "linux_ppc64"
# define DKML_ABI_linux_ppc64
Expand Down
Loading