Current section
Files
Jump to
Current section
Files
Makefile.win
# The NIF, on Windows, with MSVC and nmake — the toolchain an Elixir install on
# Windows already needs, and the one Fine's own example uses.
#
# `mix` runs this with MIX_APP_PATH, ERTS_INCLUDE_DIR and FINE_INCLUDE_DIR set,
# and with MUJOCO_DIR pointing at a MuJoCo prepared by
# scripts/prepare_mujoco.exs. The MuJoCo release ships `lib\mujoco.lib` to link
# against and `bin\mujoco.dll` to load. Both sit together in priv, which is not
# enough: Windows resolves a library's imports against the modules already in
# the process, and will not look beside the importing library. `preload.cpp`
# loads MuJoCo first, from a library of its own that imports nothing.
PRIV_DIR=$(MIX_APP_PATH)\priv
NIF_PATH=$(PRIV_DIR)\ex_mujoco_nif.dll
PRELOAD_PATH=$(PRIV_DIR)\ex_mujoco_preload.dll
C_SRC=$(EX_MUJOCO_PROJECT_DIR)\c_src
SCRIPT=$(EX_MUJOCO_PROJECT_DIR)\scripts\prepare_mujoco.exs
# `/wd4100` is MSVC for `-Wno-unused-parameter`: a NIF that does not need
# `env` is the common case, and the parameter is what Fine calls through.
# `/wd4611` is the `setjmp` / destructor warning, and it is the one caveat this
# design owns: MuJoCo's fatal error is caught by a longjmp, and the lambda the
# call runs in owns nothing that needs unwinding. `c_src/mj_call.hpp` says so.
CPPFLAGS=/LD /std:c++17 /W4 /WX /EHsc /O2 /wd4100 /wd4611
CPPFLAGS=$(CPPFLAGS) /I"$(ERTS_INCLUDE_DIR)" /I"$(FINE_INCLUDE_DIR)"
CPPFLAGS=$(CPPFLAGS) /I"$(MUJOCO_DIR)\include" /I"$(C_SRC)"
LDFLAGS=/link /LIBPATH:"$(MUJOCO_DIR)\lib" mujoco.lib
SOURCES=$(C_SRC)\ex_mujoco_nif.cpp
PRELOAD_SOURCES=$(C_SRC)\preload.cpp
FINE_HEADERS=$(FINE_INCLUDE_DIR)\*.hpp
all: mujoco $(NIF_PATH) $(PRELOAD_PATH)
mujoco:
@ elixir "$(SCRIPT)" --ensure --priv "$(PRIV_DIR)"
# `/Fe` is a compiler option and has to come before `/link`; after it, `cl` hands
# it to the linker, which does not recognise it, warns, and writes the DLL under
# its default name instead of ours.
$(NIF_PATH): $(SOURCES) $(FINE_HEADERS)
@ if not exist "$(PRIV_DIR)" mkdir "$(PRIV_DIR)"
cl $(CPPFLAGS) $(SOURCES) /Fe"$(NIF_PATH)" $(LDFLAGS)
# No `mujoco.lib`: this one is built to load MuJoCo, not to call it.
$(PRELOAD_PATH): $(PRELOAD_SOURCES) $(FINE_HEADERS)
@ if not exist "$(PRIV_DIR)" mkdir "$(PRIV_DIR)"
cl $(CPPFLAGS) $(PRELOAD_SOURCES) /Fe"$(PRELOAD_PATH)" /link
clean:
@ if exist "$(NIF_PATH)" del /q "$(NIF_PATH)"
@ if exist "$(PRELOAD_PATH)" del /q "$(PRELOAD_PATH)"