I recently decided to go back to dabbling in
OCaml
. The easier path would have been to install it in a Linux VM and play with it there, but I decided to build it from source to use Microsoft’s C compiler. The
instructions
are clear and easy to follow. The advantage of compiling with
cl
is that while the actual build does need the Cygwin tools, the resulting binaries have no restrictions on them as they are not linked with the Cygwin DLL.
After
ocaml
itself was built and installed, it was
opam
next. Similarly, build and install were uneventful, made easy by the availability of excellent instructions.
Once
opam
was installed and initialized, I tried
opam install core
to install
JaneStreet’s Core
library. The installation failed because
core_kernel
depends on
time_now
and
time_now
does not compile with MS Visual C:
* install time_now v0.14.0
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
▼ retrieved time_now.v0.14.0 (cached)
[ERROR] The compilation of time_now.v0.14.0 failed at "dune build -p time_now -j 1".
#=== ERROR while compiling time_now.v0.14.0 ===================================#
# context 2.1.0~rc2 | win32/x86_64 | ocaml.4.12.0 | https://opam.ocaml.org#6609b442
# path ~\.opam\default\.opam-switch\build\time_now.v0.14.0
# command ~\.opam\default\bin\dune.exe build -p time_now -j 1
# exit-code 1
# env-file ~\.opam\log\time_now-8632-6ce4ee.env
# output-file ~\.opam\log\time_now-8632-6ce4ee.out
### output ###
# cl src/time_now_stubs.obj (exit 2)
# (cd _build/default/src && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\
VC\Tools\MSVC\14.29.30037\bin\HostX64\x64\cl.exe" -nologo -O2 -Gy- -MD -D_CRT_SECURE_NO_DEP
RECATE -nologo -O2 -Gy- -MD -I c:/opt/ocaml/lib/ocaml -I C:\opt\cygwin64\home\user\.opam\d
efault\lib\base -I C:\opt\cygwin64\home\user\.opam\default\lib\base\base_internalhash_type
s -I C:\opt\cygwin64\home\user\.[...]
# time_now_stubs.c
# time_now_stubs.c(25): fatal error C1083: Cannot open include file: 'sys/time.h': No such
file or directory
If you look at the
time_now source code
, the reason is easy to easy to see: POSIX
clock_gettime
is not available, so we try to compile the fallback which uses
gettimeofday
whose prototype comes from the non-standard
sys/time.h
in that while it is generally available on Linux, it is not in any C standard. A simple Google search for getting time in nanoseconds on Windows yields a number of cases where people wrote a simple function that provided the same prototype and similar functionality to use with older Microsoft compilers: E.g.,
gettimeofday in PostgreSQL
,
gettimeofday on Stackoverflow
, or an
implementation
in
Webstone
.
I decided to dig a little deeper instead of copying and pasting one of these solutions.
It turns out, MS Visual C has supported timespec_get since Visual Studio 2015:
C:\> cl /?
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
Compiling and executing the following C program:
I opened a PR to provide a standard timespec_get
implementation when time_now
is being compiled with recent versions of cl
. The PR is limited in scope on purpose as I do not want to impose on the library authors a choice to move away from stuff that works well enough on POSIX/Linux systems just to cater to this specific case.
I also added the information to two of the questions I found on Stackoverflow: What should I use to replace gettimeofday() on Windows? and Equivalent of gettimeday() for Windows. The original questions/answers predate the availability of timespec_get
and are reasonable, but, these days, it is possible to use the standard C function.
Finally, if you are using C++, not that Visual C++ provides C++17 and experimental C++20 support and it pays to keep an eye on chrono.
PS: You can discuss this post on HN.