Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ endif

CP ?= cp
OCB_COMPFLAGS ?= -w @14@29 -w +L -w +R -w +Z -I src -I plugin-lib -I bin -I +unix -safe-string -bin-annot -strict-sequence
OCB_LINKFLAGS ?= -I +unix -I src
OCB_LINKFLAGS ?= -I +unix -I src $(OCB_EXTRA_LINKFLAGS)

PACK_CMO= $(addprefix src/,\
const.cmo \
Expand Down Expand Up @@ -179,7 +179,7 @@ configure:
$(MAKE) -f configure.make all

# proxy rule for rebuilding configuration files directly from the main Makefile
Makefile.config src/ocamlbuild_config.ml:
Makefile.config src/ocamlbuild_config.ml: src/ocamlbuild_config.ml.in
$(MAKE) -f configure.make $@

clean::
Expand Down
76 changes: 63 additions & 13 deletions configure.make
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
# from the main Makefile, but this made it not robust to addition of
# new variables to this ocaml/Makefile.config that we do not control.

include $(shell ocamlc -where)/Makefile.config
OCAML_LIBDIR = $(shell ocamlc -where)
include $(OCAML_LIBDIR)/Makefile.config

OCAML_PREFIX = $(PREFIX)
OCAML_BINDIR = $(BINDIR)
OCAML_LIBDIR = $(LIBDIR)
OCAML_MANDIR = $(MANDIR)

# If you want to affect ocamlbuild's configuration by passing variable
Expand All @@ -29,6 +29,35 @@ OCAMLBUILD_MANDIR ?= \
$(or $(shell opam config var man 2>/dev/null),\
$(OCAML_MANDIR))

# OCAMLBUILD_RELOCATABLE is true if:
# 1. The compiler is Relocatable OCaml
# 2. The ocamlbuild will be installed in the same directory as the compiler
# 3. OCAMLBUILD_LIBDIR is an explicit relative path (i.e. begins ./ or ../)
# OCAMLBUILD_RELOCATABLE is empty if any of these things are not true.
OCAMLBUILD_LIBDIR_RELATIVE = $(filter . .. ./% ../%, $(OCAMLBUILD_LIBDIR))
OCAML_RELOCATABLE = \
$(shell ocamlc -config-var standard_library_relative 2>/dev/null)
OCAMLC_BIN_DIR = $(abspath $(dir $(shell command -v ocamlc)))
# On Windows, OCAMLC_BIN_DIR will be a Cygwin-style path but OCAMLBUILD_BINDIR
# is a native path. The requirement is that the OCAMLBUILD_BINDIR needs to be
# the same as the compiler - that means it _must_ already exist, so it gets
# canonicalised using "poor man's realpath" by doing cd+pwd.
OCAMLBUILD_BINDIR_RESOLVED = $(shell cd '$(OCAMLBUILD_BINDIR)' 2>/dev/null ; pwd)
OCAMLBUILD_RELOCATABLE := \
$(if $(OCAMLBUILD_LIBDIR_RELATIVE),$\
$(if $(OCAML_RELOCATABLE),$\
$(if $(filter $(abspath $(OCAMLBUILD_BINDIR_RESOLVED)),$(OCAMLC_BIN_DIR)),true)))

# If OCAMLBUILD_LIBDIR is an explicit relative path, but Relocatable ocamlbuild
# cannot be built (see above), then OCAMLBUILD_LIBDIR_ACTUAL is the absolute
# path calculated by concatenating OCAML_LIBDIR and OCAMLBUILD_LIBDIR. Otherwise
# it is just OCAMLBUILD_LIBDIR.
OCAMLBUILD_LIBDIR_ACTUAL := \
$(if $(OCAMLBUILD_RELOCATABLE),$(OCAMLBUILD_LIBDIR),$\
$(if $(OCAMLBUILD_LIBDIR_RELATIVE),$\
$(if $(filter .., $(OCAMLBUILD_LIBDIR)),$(dir $(OCAML_LIBDIR)),$\
$(abspath $(OCAML_LIBDIR)/$(OCAMLBUILD_LIBDIR)),$(OCAMLBUILD_LIBDIR))))

# It is important to distinguish OCAML_LIBDIR, which points to the
# directory of the ocaml compiler distribution, and OCAMLBUILD_LIBDIR,
# which should be the general library directory of OCaml projects on
Expand Down Expand Up @@ -67,11 +96,6 @@ distclean:
Makefile.config:
(echo "# This file was generated from configure.make"; \
echo ;\
echo "OCAML_PREFIX=$(OCAML_PREFIX)"; \
echo "OCAML_BINDIR=$(OCAML_BINDIR)"; \
echo "OCAML_LIBDIR=$(OCAML_LIBDIR)"; \
echo "OCAML_MANDIR=$(OCAML_MANDIR)"; \
echo ;\
echo "EXT_OBJ=$(EXT_OBJ)"; \
echo "EXT_ASM=$(EXT_ASM)"; \
echo "EXT_LIB=$(EXT_LIB)"; \
Expand All @@ -82,20 +106,45 @@ Makefile.config:
echo "OCAML_NATIVE_TOOLS=$(OCAML_NATIVE_TOOLS)"; \
echo "NATDYNLINK=$(NATDYNLINK)"; \
echo "SUPPORT_SHARED_LIBRARIES=$(SUPPORTS_SHARED_LIBRARIES)"; \
echo "OCB_EXTRA_LINKFLAGS=$(OCB_EXTRA_LINKFLAGS)"; \
echo ;\
echo "PREFIX=$(OCAMLBUILD_PREFIX)"; \
echo "BINDIR=$(OCAMLBUILD_BINDIR)"; \
echo "LIBDIR=$(OCAMLBUILD_LIBDIR)"; \
echo "LIBDIR=$(OCAMLBUILD_LIBDIR_ACTUAL)"; \
echo "MANDIR=$(OCAMLBUILD_MANDIR)"; \
) > $@

src/ocamlbuild_config.ml:
ifeq ($(OCAMLBUILD_RELOCATABLE), true)

# For Relocatable ocamlbuild, just record the relative path specified for
# OCAMLBUILD_LIBDIR and the current directory name (".") for BINDIR and the
# extra code apppended from src/ocamlbuild_config.ml.in will process the correct
# values at runtime.
src/ocamlbuild_config.ml: BINDIR = .
src/ocamlbuild_config.ml: OCAML_LIBDIR =
src/ocamlbuild_config.ml: LIBDIR_ABS =

OCB_EXTRA_LINKFLAGS = \
-set-runtime-default standard_library_default=$(OCAML_RELOCATABLE)

else

# For normal ocamlbuild, record the configured values.
src/ocamlbuild_config.ml: BINDIR := $(OCAMLBUILD_BINDIR)
src/ocamlbuild_config.ml: OCAML_LIBDIR := $(abspath $(OCAML_LIBDIR))
src/ocamlbuild_config.ml: LIBDIR_ABS := $(abspath $(OCAMLBUILD_LIBDIR_ACTUAL))

OCB_EXTRA_LINKFLAGS =

endif

src/ocamlbuild_config.ml: src/ocamlbuild_config.ml.in
(echo "(* This file was generated from ../configure.make *)"; \
echo ;\
echo 'let bindir = {|$(OCAMLBUILD_BINDIR)|}'; \
echo 'let libdir = {|$(OCAMLBUILD_LIBDIR)|}'; \
echo 'let ocaml_libdir = {|$(abspath $(OCAML_LIBDIR))|}'; \
echo 'let libdir_abs = {|$(abspath $(OCAMLBUILD_LIBDIR))|}'; \
echo 'let bindir = {|$(BINDIR)|}'; \
echo 'let libdir = {|$(OCAMLBUILD_LIBDIR_ACTUAL)|}'; \
echo 'let ocaml_libdir = {|$(OCAML_LIBDIR)|}'; \
echo 'let libdir_abs = {|$(LIBDIR_ABS)|}'; \
echo 'let ocaml_native = $(OCAML_NATIVE)'; \
echo 'let ocaml_native_tools = $(OCAML_NATIVE_TOOLS)'; \
echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\
Expand All @@ -105,4 +154,5 @@ src/ocamlbuild_config.ml:
echo 'let ext_dll = "$(EXT_DLL)"'; \
echo 'let exe = "$(EXE)"'; \
echo 'let version = "$(shell ocaml scripts/cat.ml VERSION)"'; \
$(if $(OCAMLBUILD_RELOCATABLE),cat src/ocamlbuild_config.ml.in;) \
) > $@
2 changes: 1 addition & 1 deletion ocamlbuild.opam
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ build: [
"all"
"OCAMLBUILD_PREFIX=%{prefix}%"
"OCAMLBUILD_BINDIR=%{bin}%"
"OCAMLBUILD_LIBDIR=%{lib}%"
"OCAMLBUILD_LIBDIR=.."
"OCAMLBUILD_MANDIR=%{man}%"
"OCAML_NATIVE=%{ocaml:native}%"
"OCAML_NATIVE_TOOLS=%{ocaml:native}%"
Expand Down
35 changes: 35 additions & 0 deletions src/ocamlbuild_config.ml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#2 "ocamlbuild_config.ml.in"
(***********************************************************************)
(* *)
(* ocamlbuild *)
(* *)
(* David Allsopp, Tarides *)
(* *)
(* Copyright 2025 David Allsopp Ltd. All rights reserved. This *)
(* file is distributed under the terms of the GNU Library General *)
(* Public License, with the special exception on linking described *)
(* in file ../LICENSE. *)
(* *)
(***********************************************************************)

(* Compute the effective default for the Standard Library *)
let ocaml_libdir, bindir =
let module Defs = struct
external default : unit -> string = "%standard_library_default"
external get : string -> string * string option = "caml_sys_get_stdlib_dirs"
end in
match Defs.get (Defs.default ()) with
| ocaml_libdir, Some bindir ->
ocaml_libdir, bindir
| ocaml_libdir, None ->
(* This code should in theory only be being executed on a relocatable
runtime *)
ocaml_libdir, Filename.dirname Sys.executable_name

let libdir =
if libdir = ".." then
(* Cheeky special case, as it happens to match opam *)
Filename.dirname ocaml_libdir
else
(* General case *)
Filename.concat ocaml_libdir libdir