package dkml-c-probe

  1. Overview
  2. Docs
Cross-compiler friendly characterizations of the OCaml's native C compiler

Install

Dune Dependency

Authors

Maintainers

Sources

v2.0.0.tar.gz
md5=e7d634b9fb19e4faa712a7bf7198839a
sha512=5276ef54e0d2b13baf9d888601b64331e67c4bfeabf9526046e2fb85c6e41273c84eeffe9cd4dd7eb66964021f15b656c97dc2597313f5664c4bddf72dde18c5

Description

Using the C compiler of ocamlopt -config, which may be a cross-compiler, vends an OCaml module with enumerations of the target operating system and ABI, and a C header that introspects the same at compile time

Published: 01 Jun 2022

README

dkml-c-probe

Introspects OCaml's native C compiler to determine the ABI used by executables created by the C compiler. Designed to be used to simplify Dune Configurator code or foreign C stub code. Since dkml-c-probe never runs executables created by the C compiler, dkml-c-probe is safe to use with cross-compilers.

For example, let's say you had an Apple Intel x86_64 build machine with a OCaml ocamlfind cross-compiler toolchain for Apple Silicon. This will be available soon from Opam: https://github.com/diskuv/dkml-compiler/blob/main/dkml-base-compiler.opam

OCaml will report:

$ ocamlopt -config
...
native_c_compiler: clang -arch x86_64

$ ocamlfind -toolchain darwin_arm64 ocamlopt -config
...
native_c_compiler: clang -arch arm64

which would mean:

Lazy.force (Dkml_c_probe.C_abi.V2.get_abi ())

would result in Ok Darwin_x86_64 or Ok Darwin_arm64, depending on which ocamlfind toolchain was used.

Dune Cross Compilation combined with Opam Monorepo makes this simpler. On the same example machine you could do:

$ dune build -x darwin_arm64

and it would compile both Apple Intel and Apple Silicon binaries. During the compilation of the Apple Intel binaries (Dune's "default" context) the get_abi () would give Ok Darwin_x86_64 while during the compilation of the Apple Silicon binaries (Dune's "default_arm64" context) it would give Ok Darwin_arm64.

Usage

Install it with:

$ opam install dkml-c-probe

Then either:

OCaml Signature

OCaml API documentation is at http://diskuv.github.io/dkml-c-probe/

$ ocaml show_signature.ml
module V2 = Dkml_c_probe.C_abi.V2
module V2 :
  sig
    type t_os = Android | IOS | Linux | OSX | Windows
    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
      | Windows_arm64
      | Windows_arm32
    val get_os : (t_os, Rresult.R.msg) result Lazy.t
    val get_abi : (t_abi, Rresult.R.msg) result Lazy.t
    val get_abi_name : (string, Rresult.R.msg) result Lazy.t
  end

C Header

The header file will be available as the following expressions:

  • %{dkml-c-probe:lib}%/dkml_compiler_probe.h if you are in an .opam file

  • %{lib:dkml-c-probe:dkml_compiler_probe.h} if you are in a dune file

/******************************************************************************/
/*  Copyright 2021 Diskuv, Inc.                                               */
/*                                                                            */
/*  Licensed under the Apache License, Version 2.0 (the "License");           */
/*  you may not use this file except in compliance with the License.          */
/*  You may obtain a copy of the License at                                   */
/*                                                                            */
/*      http://www.apache.org/licenses/LICENSE-2.0                            */
/*                                                                            */
/*  Unless required by applicable law or agreed to in writing, software       */
/*  distributed under the License is distributed on an "AS IS" BASIS,         */
/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  */
/*  See the License for the specific language governing permissions and       */
/*  limitations under the License.                                            */
/******************************************************************************/

/*
  For Apple see https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary
  For Windows see https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-160
  For Android see https://developer.android.com/ndk/guides/cpu-features
  For Linux see https://sourceforge.net/p/predef/wiki/Architectures/
 */
#ifndef DKMLCOMPILERPROBE_H
#define DKMLCOMPILERPROBE_H

#if __APPLE__
#   include <TargetConditionals.h>
#   if TARGET_OS_OSX
#       define DKML_OS_NAME "OSX"
#       define DKML_OS_OSX
#       if TARGET_CPU_ARM64
#           define DKML_ABI "darwin_arm64"
#           define DKML_ABI_darwin_arm64
#       elif TARGET_CPU_X86_64
#           define DKML_ABI "darwin_x86_64"
#           define DKML_ABI_darwin_x86_64
#       elif TARGET_CPU_PPC64
#           define DKML_ABI "darwin_ppc64"
#           define DKML_ABI_darwin_ppc64
#       endif /* TARGET_CPU_ARM64, TARGET_CPU_X86_64, TARGET_CPU_PPC64 */
#   elif TARGET_OS_IOS
#       define DKML_OS_NAME "IOS"
#       define DKML_OS_IOS
#       define DKML_ABI "darwin_arm64"
#       define DKML_ABI_darwin_arm64
#   endif /* TARGET_OS_OSX, TARGET_OS_IOS */
#elif __linux__
#   if __ANDROID__
#       define DKML_OS_NAME "Android"
#       define DKML_OS_Android
#       if __arm__
#           define DKML_ABI "android_arm32v7a"
#           define DKML_ABI_android_arm32v7a
#       elif __aarch64__
#           define DKML_ABI "android_arm64v8a"
#           define DKML_ABI_android_arm64v8a
#       elif __i386__
#           define DKML_ABI "android_x86"
#           define DKML_ABI_android_x86
#       elif __x86_64__
#           define DKML_ABI "android_x86_64"
#           define DKML_ABI_android_x86_64
#       endif /* __arm__, __aarch64__, __i386__, __x86_64__ */
#   else
#       define DKML_OS_NAME "Linux"
#       define DKML_OS_Linux
#       if __aarch64__
#           define DKML_ABI "linux_arm64"
#           define DKML_ABI_linux_arm64
#       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"
#               define DKML_ABI_linux_arm32v6
#           elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
#               define DKML_ABI "linux_arm32v7"
#               define DKML_ABI_linux_arm32v7
#           endif /* __ARM_ARCH_6__ || ...,  __ARM_ARCH_7__ || ... */
#       elif __x86_64__
#           define DKML_ABI "linux_x86_64"
#           define DKML_ABI_linux_x86_64
#       elif __i386__
#           define DKML_ABI "linux_x86"
#           define DKML_ABI_linux_x86
#       elif defined(__ppc64__) || defined(__PPC64__)
#           define DKML_ABI "linux_ppc64"
#           define DKML_ABI_linux_ppc64
#       elif __s390x__
#           define DKML_ABI "linux_s390x"
#           define DKML_ABI_linux_s390x
#       endif /* __aarch64__, __arm__, __x86_64__, __i386__, __ppc64__ || __PPC64__, __s390x__ */
#   endif /* __ANDROID__ */
#elif _WIN32
#   define DKML_OS_NAME "Windows"
#   define DKML_OS_Windows
#   if _M_ARM64
#       define DKML_ABI "windows_arm64"
#       define DKML_ABI_windows_arm64
#   elif _M_ARM
#       define DKML_ABI "windows_arm32"
#       define DKML_ABI_windows_arm32
#   elif _WIN64
#       define DKML_ABI "windows_x86_64"
#       define DKML_ABI_windows_x86_64
#   elif _M_IX86
#       define DKML_ABI "windows_x86"
#       define DKML_ABI_windows_x86
#   endif /* _M_ARM64, _M_ARM, _WIN64, _M_IX86 */
#endif

#endif /* DKMLCOMPILERPROBE_H */

Contributions

We are always looking for new ABIs! Each new ABI needs to have its own maintainer.

For example, PowerPC (ppc64) and Linux on IBM Z (s390x) are supported in the C Header but not the OCaml Signature because there are no PowerPC and S390x maintainers.

If you are interested, head over to Your Contributions.

Status

Status
Syntax check

Dependencies (5)

  1. dune-configurator >= "2.9" & build
  2. astring >= "0.8.5"
  3. rresult >= "0.6.0"
  4. ocaml >= "4.12.1"
  5. dune >= "2.9"

Dev Dependencies (2)

  1. odoc with-doc
  2. mdx >= "2.0.0" & with-test

Used by

None

Conflicts (1)

  1. result < "1.5"