package config
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=6dc4427cb5f6ae8f2f9d04c9897d9a606242f9e0f6eaf90fca731883cd7b6053
sha512=a3f81bf8975f6f8d69c8c1b4cc041f37be19b311797573f960afaf21beac99292e255c87ee661f40be8e5f1aaf27a64754e0a6155ef0f9785024cea0c17f8eb9
Description
Config implements the [@@config] annotation, to conditionally compile modules. You can use a small boolean language to check for conditions including some built-in ones and environment variables.
README
config.ml
Ergonomic, lightweight conditional compilation through attributes inspired by Rust's cfg macro.
Config implements the [@@config] annotation, to conditionally compile modules. You can use a small boolean language to check for conditions including some built-in ones and environment variables.
It can be used to conditionally include/exclude:
- modules
- let bindings
- includes
- type definitions
- constructors from variant types and polymorphic variants
- fields from record types
- and more
Currently includes/detects the following platforms:
- Windows 32/64
- macOS/tvOS/watchOS/iOS
- FreeBSD/NetBSD
- Android
- Linux
And the following architectures:
- x86-64
- x86 i386
- aarch64
- arm
And the following environment:
- msvc
- gnu
- musl
Getting Started
opam install configAnd add it to your dune files:
(library
(name my_lib)
(preprocess (pps config.ppx)))And tag your values with the @@config or @@cfg attribute:
module A = A_unix [@@config any(target_os = "macos", target_os = "linux")]
module A = A_win32 [@@cfg any(target_os = "windows")]The Config Language
Config implements a very small boolean language with 4 operations:
var = value, that checks if a variable (from the environment or provided by config) is equals to a value. Equality is string or integer equality.all(expr1, expr2, ...), expects all expressions to be trueany(expr1, expr2, ...), expects any expression to be truenot(expr), negates an expression
To define new variables you can pass them in as environment variables:
; export BAND="rush" dune buildAnd you'll be able to write (BAND = "rush")
Cookbook
Enabling/Disabling Modules and Includes
module Pro_mode_env = struct
let name = "pro-mode"
let coins = 2112
end
[@@config (project_mode = "pro")]
include Pro_mode_env
[@@config (project_mode = "pro")]
module A : sig
val name : string [@@cfg (project_mode = "pro")]
end = struct
let name = "Product" [@@cfg (project_mode = "pro")]
end Enabling/Disabling Let definitions
let favorite_band = "rush"
[@@config (is_rush_fan = true)]
let favorite_band = "unknown"
[@@config not (is_rush_fan = true)]Enabling/Disabling Externals
external dog_bark : unit -> int = "dog_bark"
[@@config (includes = "dog")]Enabling/Disabling Types
type band = { name: string }
[@@config (use_band = true)]Enabling/Disabling Variant Constructors
type favorite_bands =
| Rush
| Yes
| KingCrimson [@config (likes_trumpets = true)]
let is_favorite x =
match x with
| Rush -> true
| Yes -> false
| KingCrimson -> false [@config (likes_trumpets = true)]
type has_published_album_recently =
[ `nope
| `yes
| `maybe [@config (is_indecisive = true)]
]
let get_has_published (x: has_published_album_recently) =
match x with
| `nope -> true
| `yes -> false
| `maybe -> false [@config (is_indecisive = true)]Enabling/Disabling Record Fields
type user = {
name: string;
pass: string [@config (password_mode = "clear")];
pass: Password.t [@config (password_mode = "encrypted")];
}Enabling/Disabling entire Modules
[@@@config (should_include = "no")]
let do_not_include_me = failwith "oh no"Contributing
Currently config relies on C preprocessor definitions to detect different platforms and architectures. They are straightforward to add by extending the file ./config/config_stubs.cl. In there :
- To add a new platform, extend the main if-else chain in the
caml_config_target_osfunction to include your OS. - To add a new architecture, extend the main if-else chain in the
caml_config_target_archfunction to include your architecture.