Is there a programmable way to check for Darwin (Mac OS X) or Linux?

Currently, I do this, but that’s not very classy:

let sed_cmd =
  match Utls.get_command_output "uname" with
  | "Darwin" -> "gsed"
  | "Linux" -> "sed"
  | other -> (Log.fatal "unsupported OS: %s" other;
              exit 1)

I wonder if the Sys module could not provide something…

2 Likes

Sys.os_type doesn’t distinguish between Mac OS and other Unix-kind of systems.
I think that interpreting the result of uname is a bit out of the scope of your program.

I suggest looking up for gsed first then fallback to sed if it can’t be found. (eg. change your program from “gsed on macos, sed otherwise” to “gsed if available, sed otherwise”)
command -v gsed will search the PATH or exit with an error status. It’s a shell builtin required by posix, I think.

1 Like

Here’s how I did it in directories. For a better way, you could look at how it’s done in opam I don’t remember where it is but I had a look a while ago and it was way better than what I did in directories.

EDIT: I asked @rjbou and here some stuff in opam that might be helpful: syspoll and initdefault ; for initdefault you can get a readable version with opam init --show-default-opamrc

$ gsed
-bash: gsed: command not found
$ uname -a
Darwin MacBook-Pro 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64

I wonder if a more portable script would be an option?

Out of curiosity, why not support Windows?

If you don’t mind compile some C code, here’s how Jason Hickey’s libmojave does it, and it is compatible with Win32:

I would recommend you to use the C preprocessor for this, dune-configurator is really cool on this aspect .

On revery we have it for a couple OS, Android, Linux, iOS, macOS and Windows.

2 Likes

Because I don’t need and don’t even have access to it.

we need a conf-gsed; it could ask brew to install gsed if needed

1 Like

I suppose the same script could also install a “gsed” link to “sed” where appropriate.

More generally this kind of thing, if it’s really necessary, is done with feature-specific tests. If it were a C application, autoconfig would generate an include file with features like #define GNU_SED "gsed", and the code would compile with that macro. In Ocaml I guess it would be a Host module or something. When you haven’t yet had to maintain your application for more than a couple platforms, it might sound like extra trouble, but in the long run it makes more sense than trying to guess from the OS the way we used to do 30 years ago.

I think it is a bad idea to assume everyone uses brew on mac.

There could be several alternative choices, either

  1. write the script/whatever in a POSIX complaint way.
  2. make a OCaml reimplementation of sed on platforms without it.
  3. let the user decide which program to call, and do the necessary test to confirm that it is GNU’s sed.
2 Likes

I hate to bring this up, might be a first for me, but …

  1. see if Perl would work. I believe there’s a standard issue sed-to-perl convertor, and while Perl isn’t installed everywhere either, it appears to be far more widely installed than GNU sed. I haven’t used Perl since the early '90s, so don’t ask me about the details.

Options 1 or 2 would be the place to start, though.