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
83 changes: 66 additions & 17 deletions configure.make
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
# 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_PREFIX = $(prefix)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a change from $PREFIX to $prefix?

OCAML_MANDIR = $(MANDIR)

# If you want to affect ocamlbuild's configuration by passing variable
# assignments to this Makefile, you probably want to define those
# OCAMLBUILD_* variables.

OCAMLBUILD_PREFIX ?= $(PREFIX)
OCAMLBUILD_PREFIX ?= $(OCAML_PREFIX)
OCAMLBUILD_BINDIR ?= \
$(or $(shell opam config var bin 2>/dev/null),\
$(PREFIX)/bin)
$(OCAML_PREFIX)/bin)
OCAMLBUILD_LIBDIR ?= \
$(or $(shell opam config var lib 2>/dev/null),\
$(shell ocamlfind printconf destdir 2>/dev/null),\
Expand All @@ -29,6 +28,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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit obscure to me. Maybe "The compiler supports relocation and the 'standard_library_relative' configuration variable"?

# 2. ocamlbuild will be installed in the same directory as the compiler
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ocamlbuild binary will be installed in the same directory as the compiler binaries. My first reaction was that of course they should be installed in their own separate directories (I was thinking of libraries).

# 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 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 +95,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 +105,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 = \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you maybe use the same approach as above to clarify the parallel?

Makefile.config: 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 +153,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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, are there clear benefits to passing dirname ocaml_libdir rather than ocaml_libdir/..?

else
(* General case *)
Filename.concat ocaml_libdir libdir