···109# Some Unicode characters here and there
110utils/misc.ml typo.non-ascii
111runtime/sak.c typo.non-ascii
0112113testsuite/tests/** typo.missing-header typo.long-line=may
114testsuite/tests/lib-bigarray-2/bigarrf.f typo.tab linguist-language=Fortran
···109# Some Unicode characters here and there
110utils/misc.ml typo.non-ascii
111runtime/sak.c typo.non-ascii
112+tools/opam/process.sh typo.non-ascii
113114testsuite/tests/** typo.missing-header typo.long-line=may
115testsuite/tests/lib-bigarray-2/bigarrf.f typo.tab linguist-language=Fortran
+35-8
.github/workflows/build-msvc.yml
···33 with:
34 script: |
35 // # Always test cl and clang-cl
36- let compilers = ['cl', 'clang-cl'];
37 // # Also test i686 MSVC
38 let include = [
39- {cc: 'cl', arch: 'i686', libdir: 'relative'}];
0040 let libdir = ['absolute'];
41 // # If this is a pull request, see if the PR has the
42 // # 'CI: Full matrix' label. This is done using an API request,
···53 // # Test Cygwin as well
54 compilers.push('gcc');
55 // # Test bytecode-only Cygwin
56- include.push({cc: 'gcc', arch: 'x86_64', libdir: 'absolute', config_arg: '--disable-native-toplevel --disable-native-compiler'});
57 // # Test i686 MSVC absolute
58- include.push({cc: 'cl', arch: 'i686', libdir: 'absolute'});
59 // # Expand the main matrix to include relative testing
60 libdir.push('relative');
61 }
62 }
63- return {config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include};
64 - name: Determine if the testsuite should be skipped
65 id: skip
66 uses: actions/github-script@v7
···78 build:
79 permissions: {}
8081- runs-on: windows-latest
8283 needs: config
84···107 - name: Install Cygwin
108 uses: cygwin/cygwin-install-action@v3
109 with:
110- packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-g++,gcc-fortran,' }}gcc-core
111 install-dir: 'D:\cygwin'
112113 - name: Save Cygwin cache
···123 arch: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }}
124 if: matrix.cc != 'gcc'
1250000000126 - name: Compute a key to cache configure results
127 id: autoconf-cache-key
128 env:
···141 env:
142 CONFIG_ARGS: >-
143 --cache-file=config.cache
144- --prefix "${{ matrix.cc != 'gcc' && '$PROGRAMFILES\\Бактріан🐫' || '$(cygpath "$PROGRAMFILES/Бактріан🐫")'}}"
0145 ${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }}
146 ${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }}
147 --enable-ocamltest
···200 make tests
201202 - name: Install the compiler
0203 run: make install
0000000000000000204205 - name: Test in prefix
206 run: |
···33 with:
34 script: |
35 // # Always test cl and clang-cl
36+ let compilers = ['clang-cl'];
37 // # Also test i686 MSVC
38 let include = [
39+ {os: 'windows-latest', cc: 'cl', arch: 'i686', opam: 'false', prefix: '$PROGRAMFILES/Бактріан🐫', libdir: 'relative'},
40+ {os: 'windows-2025', cc: 'cl', arch: 'x86_64', opam: 'true', prefix: 'C:\\\\Бактріан🐫'},
41+ {os: 'windows-2025', cc: 'cl', arch: 'i686', opam: 'true', prefix: 'C:\\\\Бактріан🐫'}];
42 let libdir = ['absolute'];
43 // # If this is a pull request, see if the PR has the
44 // # 'CI: Full matrix' label. This is done using an API request,
···55 // # Test Cygwin as well
56 compilers.push('gcc');
57 // # Test bytecode-only Cygwin
58+ include.push({os: 'windows-latest', prefix: '$PROGRAMFILES/Бактріан🐫', opam: ['false'], cc: 'gcc', arch: 'x86_64', libdir: 'absolute', config_arg: '--disable-native-toplevel --disable-native-compiler'});
59 // # Test i686 MSVC absolute
60+ include.push({os: 'windows-latest', prefix: '$PROGRAMFILES/Бактріан🐫', opam: ['false'], cc: 'cl', arch: 'i686', libdir: 'absolute'});
61 // # Expand the main matrix to include relative testing
62 libdir.push('relative');
63 }
64 }
65+ return {os: ['windows-latest'], prefix: ['$PROGRAMFILES/Бактріан🐫'], opam: ['false'], config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include};
66 - name: Determine if the testsuite should be skipped
67 id: skip
68 uses: actions/github-script@v7
···80 build:
81 permissions: {}
8283+ runs-on: ${{ matrix.os }}
8485 needs: config
86···109 - name: Install Cygwin
110 uses: cygwin/cygwin-install-action@v3
111 with:
112+ packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-g++,gcc-fortran,' }}gcc-core,rsync,unzip
113 install-dir: 'D:\cygwin'
114115 - name: Save Cygwin cache
···125 arch: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }}
126 if: matrix.cc != 'gcc'
127128+ - name: Install opam
129+ if: matrix.opam == 'true'
130+ shell: pwsh
131+ run: |
132+ winget install opam --accept-source-agreements
133+ Add-Content -Path $env:GITHUB_PATH -Value "$env:LOCALAPPDATA\Microsoft\WinGet\Links"
134+135 - name: Compute a key to cache configure results
136 id: autoconf-cache-key
137 env:
···150 env:
151 CONFIG_ARGS: >-
152 --cache-file=config.cache
153+ --prefix ${{ matrix.cc != 'gcc' && format('"{0}/_opam"', matrix.prefix) || format('"$(cygpath "{0}")"', matrix.prefix) }}
154+ --docdir ${{ format((matrix.cc != 'gcc' && '"{0}/_opam/doc/ocaml"' || '"$(cygpath "{0}/doc/ocaml")"'), matrix.prefix) }}
155 ${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }}
156 ${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }}
157 --enable-ocamltest
···210 make tests
211212 - name: Install the compiler
213+ if: matrix.opam != 'true'
214 run: make install
215+216+ - name: Create opam switch
217+ if: matrix.opam == 'true'
218+ env:
219+ OPAMSWITCH: ${{ matrix.prefix }}
220+ run: |
221+ make OPAM_PACKAGE_NAME=ocaml-variants INSTALL_MODE=opam install
222+ opam init --cli=2.4 --bare --yes --disable-sandboxing --auto-setup --cygwin-local-install
223+ # These commands intentionally run using opam's "default" CLI
224+ opam switch create '${{ env.OPAMSWITCH }}' --empty
225+ opam pin add --no-action --kind=path ocaml-variants .
226+ opam pin add --no-action flexdll flexdll
227+ opam pin add --no-action winpthreads winpthreads
228+ opam install --yes flexdll winpthreads
229+ opam install --yes --assume-built ocaml-variants
230+ opam exec -- ocamlc -v
231232 - name: Test in prefix
233 run: |
+11-4
.github/workflows/build.yml
···78# debug runtime and minor heap verification.
79# debug-s4096: select testsuite run with the debug runtime and a small
80# minor heap.
081 normal:
82 name: ${{ matrix.name }}
83 needs: [build, config]
···88 - id: normal
89 name: normal
90 dependencies: texlive-latex-extra texlive-fonts-recommended texlive-luatex hevea sass gdb lldb
0091 - id: debug
92 name: extra (debug)
93 - id: debug-s4096
···134 - name: Install
135 if: matrix.id == 'normal'
136 run: |
137- MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh install
0000138 - name: Test in prefix
139- if: matrix.id == 'normal'
140 run: |
141- MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test-in-prefix
142 - name: Test in prefix (alternate configuration)
143 if: matrix.id == 'normal' && needs.config.outputs.full-matrix == 'true'
144 run: |
145- MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh re-test-in-prefix
146 - name: Build the manual
147 if: matrix.id == 'normal' && needs.build.outputs.manual_changed == 'true'
148 run: |
···78# debug runtime and minor heap verification.
79# debug-s4096: select testsuite run with the debug runtime and a small
80# minor heap.
81+# opam: constructs an opam local switch from the compiler.
82 normal:
83 name: ${{ matrix.name }}
84 needs: [build, config]
···89 - id: normal
90 name: normal
91 dependencies: texlive-latex-extra texlive-fonts-recommended texlive-luatex hevea sass gdb lldb
92+ - id: opam
93+ name: opam installation
94 - id: debug
95 name: extra (debug)
96 - id: debug-s4096
···137 - name: Install
138 if: matrix.id == 'normal'
139 run: |
140+ MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh install
141+ - name: Create opam switch
142+ if: matrix.id == 'opam'
143+ run: |
144+ MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh opam
145 - name: Test in prefix
146+ if: matrix.id == 'normal' || matrix.id == 'opam'
147 run: |
148+ MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test-in-prefix
149 - name: Test in prefix (alternate configuration)
150 if: matrix.id == 'normal' && needs.config.outputs.full-matrix == 'true'
151 run: |
152+ MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh re-test-in-prefix
153 - name: Build the manual
154 if: matrix.id == 'normal' && needs.build.outputs.manual_changed == 'true'
155 run: |
···16# The main Makefile
1718ROOTDIR = .
19+SUBDIR_NAME =
20+21# NOTE: it is important that the OCAMLDEP and OCAMLLEX variables
22# are defined *before* Makefile.common gets included, so that
23# their local definitions here take precedence over their
···53PERVASIVES=$(STDLIB_MODULES) outcometree topprinters topdirs toploop
5455LIBFILES=stdlib.cma std_exit.cmo *.cmi $(HEADER_NAME)
005657TOPINCLUDES=$(addprefix -I otherlibs/,$(filter-out %threads,$(OTHERLIBRARIES)))
58···935 rm -f flexlink.opt flexlink.opt.exe \
936 $(OPT_BINDIR)/flexlink $(OPT_BINDIR)/flexlink.exe
93700938FLEXDLL_MANIFEST = default$(filter-out _i386,_$(ARCH)).manifest
939940DOC_FILES=\
···986endif
987988partialclean::
989+ rm -f ocamlc ocamlc.exe ocamlc.opt ocamlc.opt.exe ocamlc*.stripped
990991# The native-code compiler
992···997ocamlopt_BYTECODE_LINKFLAGS = -g
998999partialclean::
1000+ rm -f ocamlopt ocamlopt.exe ocamlopt.opt ocamlopt.opt.exe ocamlopt*.stripped
10011002# The toplevel
1003···2747 $(BYTE_BUILD_TREE) $(OPT_BUILD_TREE)
2748 rm -f config.log config.status libtool
27492750+# COMPILER_ARTEFACT_DIRS adds the common compiler-libs directories as prefixes
2751+# to a sequence of patterns in the first argument, e.g.
2752+# $(call COMPILER_ARTEFACT_DIRS, *.cmi) expands to utils/*.cmi, parsing/*.cmi,
2753+# and so forth. Multiple wildcard patterns may be supplied. An optional second
2754+# argument includes additional directories beyond the common ones (e.g. asmcomp,
2755+# etc.)
2756+COMPILER_ARTEFACT_DIRS = \
2757+ $(foreach dir, \
2758+ utils parsing typing bytecomp file_formats lambda driver toplevel \
2759+ $(if $(filter-out undefined, $(origin 2)), $(2)), \
2760+ $(addprefix $(dir)/, $(1)))
2761+NATIVE_ARTEFACT_DIRS = \
2762+ asmcomp toplevel/native \
2763+ middle_end middle_end/closure middle_end/flambda middle_end/flambda/base_types
27642765# Installation
2766+# Historically, the install target dynamically installed what had been built,
2767+# for example, if only world had been built then make install simply didn't
2768+# install the native tools. That infrastructure is potentially convenient when
2769+# working on the compiler, but potentially masks bugs. It is better to have the
2770+# installation targets require everything configure mandated to have built.
2771+# There are three entry points to installation:
2772+# install - installs everything
2773+# installopt - installs the native code compiler _and_ the extra .opt tools
2774+# installoptopt - installs just the extra .opt tools
2775+# The installopt targets have been maintained for now, but may be removed in the
2776+# future.
27772778+ifeq "$(NATIVE_COMPILER)" "true"
2779+install: full-installoptopt
2780+ $(call INSTALL_END)
2781+else
2782+install: common-install
2783+ $(call INSTALL_END)
2784endif
2785+2786+# These three targets are the slightly esoteric special sauce that avoid
2787+# recursive make invocations in the install targets.
2788+# There are three basic install recipes:
2789+# - The old install target is available to common-install, but never recurses to
2790+# installopt
2791+# - The old installopt target is available as both full-installopt and
2792+# native-install
2793+# - The old installoptopt target is also available as full-installoptopt and
2794+# installopt
2795+# These sets of recipes are then welded together by these three dependency
2796+# specifications
2797+# - When configured with --disable-native-compiler, the install target simply
2798+# depends on common-install (see above)
2799+# - Otherwise, install depends on full-installoptopt (see above)
2800+# - The recipe for full-installoptopt installs the .opt versions of the tools,
2801+# but it _depends on_ full-installopt.
2802+# - full-installopt installs the native compiler, but it _depends on_
2803+# common-install
2804+installopt: native-install
2805+2806+full-installopt:: common-install
2807+2808+full-installoptopt: full-installopt
2809+2810+.PHONY: common-install
2811+common-install::
2812+ $(call INSTALL_BEGIN)
28132814ifeq "$(SUFFIXING)" "true"
2815MANGLE_RUNTIME_NAME = $(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)
···2820endif
28212822define INSTALL_RUNTIME
2823+common-install::
2824+ $$(call INSTALL_ITEM, runtime/$(1)$(EXE), bin, , \
2825+ $(call MANGLE_RUNTIME_NAME,$(1)), $(if $(filter true, $(SUFFIXING)), \
2826+ $(1)$(EXE) $(1)-$(ZINC_RUNTIME_ID)$(EXE)))
00000002827endef
2828define INSTALL_RUNTIME_LIB
2829ifeq "$(2)" "BYTECODE"
2830+common-install::
2831else
2832+full-installopt native-install::
000000002833endif
2834+ $$(call INSTALL_ITEM, runtime/lib$(1)_shared$(EXT_DLL), libexec, , \
2835+ $(call MANGLE_RUNTIME_DLL_NAME,$(1),$(2)), \
2836+ $(if $(filter true, $(SUFFIXING)), lib$(1)_shared$(EXT_DLL)))
2837endef
28382839$(foreach runtime, $(runtime_PROGRAMS), \
2840 $(eval $(call INSTALL_RUNTIME,$(runtime))))
28412842+common-install::
2843+ $(call INSTALL_ITEMS, runtime/ld.conf $(runtime_BYTECODE_STATIC_LIBRARIES), \
2844+ lib)
28452846$(foreach shared_runtime, $(runtime_BYTECODE_SHARED_LIBRARIES), \
2847 $(eval $(call INSTALL_RUNTIME_LIB,$(shared_runtime),BYTECODE)))
28482849+common-install::
2850+ $(call INSTALL_ITEMS, \
2851+ runtime/caml/domain_state.tbl runtime/caml/*.h, \
2852+ lib, $(INSTALL_LIBDIR_CAML))
2853+ $(call INSTALL_ITEMS, ocaml$(EXE), bin)
2854ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2855+ $(call STRIP_BYTE_PROG, ocamlc$(EXE))
2856+ifeq "$(NATIVE_COMPILER)" "true"
2857+ $(call INSTALL_ITEM, \
2858+ ocamlc$(EXE).stripped, bin, , ocamlc.byte$(EXE))
2859+else
2860+ $(call INSTALL_ITEM, \
2861+ ocamlc$(EXE).stripped, bin, , ocamlc.byte$(EXE), ocamlc$(EXE))
2862+endif
2863endif
2864 $(MAKE) -C stdlib install
2865+2866+define INSTALL_ONE_NAT_TOOL
2867+common-install::
2868+ifeq "$(NATIVE_COMPILER)" "true"
2869ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2870+ $$(call INSTALL_ITEM, tools/$(1)$(EXE), bin, , $(1).byte$(EXE))
2871+endif
2872+ $$(call INSTALL_ITEM, tools/$(1).opt$(EXE), bin, , , $(1)$(EXE))
0000000002873else
2874+ $$(call INSTALL_ITEM, tools/$(1)$(EXE), bin, , $(1).byte$(EXE), $(1)$(EXE))
0000002875endif
2876+endef
2877+2878+ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2879+common-install::
2880+ifeq "$(NATIVE_COMPILER)" "true"
2881+ $(call INSTALL_ITEM, \
2882+ lex/ocamllex$(EXE), bin, , ocamllex.byte$(EXE))
2883+else
2884+ $(call INSTALL_ITEM, \
2885+ lex/ocamllex$(EXE), bin, , ocamllex.byte$(EXE), ocamllex$(EXE))
2886+endif
2887+endif
2888+2889+$(foreach tool, $(TOOLS_TO_INSTALL_NAT), \
2890+ $(eval $(call INSTALL_ONE_NAT_TOOL,$(tool))))
2891+2892+define INSTALL_ONE_BYT_TOOL
2893+common-install::
2894+ $$(call INSTALL_ITEMS, tools/$(1)$(EXE), bin)
2895+endef
2896+2897+$(foreach tool, $(TOOLS_TO_INSTALL_BYT), \
2898+ $(eval $(call INSTALL_ONE_BYT_TOOL,$(tool))))
2899+2900+common-install::
2901+ $(call INSTALL_ITEMS, $(ocamlyacc_PROGRAM)$(EXE), bin)
2902+ $(call INSTALL_ITEMS, \
2903+ $(call COMPILER_ARTEFACT_DIRS, *.cmi), \
2904+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
2905ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
2906+ $(call INSTALL_ITEMS, \
2907+ $(call COMPILER_ARTEFACT_DIRS, *.cmt *.cmti *.mli), \
2908+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
2909+ $(call INSTALL_ITEMS, toplevel/byte/*.cmt, \
2910+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
2911+ $(call INSTALL_ITEMS, tools/profiling.cmt tools/profiling.cmti, \
2912+ lib, $(INSTALL_LIBDIR_PROFILING))
0000000002913endif
2914+ $(call INSTALL_ITEMS, compilerlibs/*.cma compilerlibs/META, \
2915+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
2916+ $(call INSTALL_ITEMS, $(ocamlc_CMO_FILES) $(ocaml_CMO_FILES), \
2917+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
2918+ $(call INSTALL_ITEMS, $(expunge), libexec)
002919# If installing over a previous OCaml version, ensure some modules are removed
2920# from the previous installation.
2921+ $(call INSTALL_RM, \
2922+ "$(INSTALL_LIBDIR)"/topdirs.cm* "$(INSTALL_LIBDIR)/topdirs.mli")
2923+ $(call INSTALL_RM, \
2924+ "$(INSTALL_LIBDIR)"/profiling.cm* "$(INSTALL_LIBDIR)/profiling.$(O)")
2925+ $(call INSTALL_ITEMS, tools/profiling.cmi tools/profiling.cmo, \
2926+ lib, $(INSTALL_LIBDIR_PROFILING))
2927ifeq "$(UNIX_OR_WIN32)" "unix" # Install manual pages only on Unix
2928 $(MAKE) -C man install
2929endif
2930# For dynlink, if installing over a previous OCaml version, ensure
2931# dynlink is removed from the previous installation.
2932+ $(call INSTALL_RM, \
2933+ "$(INSTALL_LIBDIR)"/dynlink.cm* \
2934+ "$(INSTALL_LIBDIR)/dynlink.mli" \
2935+ "$(INSTALL_LIBDIR)/dynlink.$(A)" \
2936+ $(addprefix "$(INSTALL_LIBDIR)/", $(notdir $(dynlink_CMX_FILES))))
2937+ $(call INSTALL_ITEMS, \
2938+ otherlibs/dynlink/dynlink.cmi otherlibs/dynlink/dynlink.cma \
2939+ otherlibs/dynlink/META, \
2940+ lib, $(INSTALL_LIBDIR_DYNLINK))
2941ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
2942+ $(call INSTALL_ITEMS, \
2943+ otherlibs/dynlink/dynlink.cmti otherlibs/dynlink/dynlink.mli, \
2944+ lib, $(INSTALL_LIBDIR_DYNLINK))
2945endif
2946 for i in $(OTHERLIBS); do \
2947 $(MAKE) -C otherlibs/$$i install || exit $$?; \
2948 done
2949ifeq "$(build_ocamldoc)" "true"
2950+ $(call INSTALL_ITEMS, ocamldoc/ocamldoc$(EXE), bin)
2951+ $(call INSTALL_ITEMS, \
2952+ ocamldoc/ocamldoc.hva ocamldoc/*.cmi ocamldoc/odoc_info.cma \
2953+ ocamldoc/META, \
2954+ lib, $(INSTALL_LIBDIR_OCAMLDOC))
00002955ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
2956+ $(call INSTALL_ITEMS, $(OCAMLDOC_LIBMLIS) $(OCAMLDOC_LIBCMTS), \
2957+ lib, $(INSTALL_LIBDIR_OCAMLDOC))
02958endif
2959endif
2960ifeq "$(build_libraries_manpages)" "true"
2961 $(MAKE) -C api_docgen install
2962endif
2963+ifneq "$(WITH_DEBUGGER)" ""
2964+ $(call INSTALL_ITEMS, debugger/ocamldebug$(EXE), bin)
2965+endif
2966ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true"
2967ifeq "$(TOOLCHAIN)" "msvc"
2968+ # Technically this should not be installed with "executable"
2969+ # permissions, but in practice that request will be ignored.
2970+ $(call INSTALL_ITEMS, $(FLEXDLL_SOURCE_DIR)/$(FLEXDLL_MANIFEST), bin)
2971endif
2972ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2973+ifeq "$(NATIVE_COMPILER)" "true"
2974+ $(call INSTALL_ITEMS, flexlink.byte$(EXE), bin)
000000000000002975else
2976+ $(call INSTALL_ITEM, flexlink.byte$(EXE), bin, , , flexlink$(EXE))
2977endif
2978+endif # ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2979+ $(call INSTALL_ITEMS, $(FLEXDLL_OBJECTS), lib, $(INSTALL_LIBDIR_FLEXDLL))
2980+endif # ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true"
2981+ $(call INSTALL_ITEMS, Makefile.config, lib)
2982+ $(call INSTALL_ITEMS, $(DOC_FILES), doc)
29832984# Installation of the native-code compiler
2985+.PHONY: full-installopt native-install
2986+full-installopt native-install::
2987+ $(call INSTALL_ITEMS, $(runtime_NATIVE_STATIC_LIBRARIES), lib)
29882989$(foreach shared_runtime, $(runtime_NATIVE_SHARED_LIBRARIES), \
2990 $(eval $(call INSTALL_RUNTIME_LIB,$(shared_runtime),NATIVE)))
29912992+full-installopt native-install::
2993ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
2994+ $(call STRIP_BYTE_PROG, ocamlopt$(EXE))
2995+ $(call INSTALL_ITEM, ocamlopt$(EXE).stripped, bin, , ocamlopt.byte$(EXE))
2996endif
2997 $(MAKE) -C stdlib installopt
2998+ $(call INSTALL_ITEMS, \
2999+ middle_end/*.cmi, \
3000+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3001+ $(call INSTALL_ITEMS, \
3002+ middle_end/closure/*.cmi, \
3003+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3004+ $(call INSTALL_ITEMS, \
3005+ middle_end/flambda/*.cmi, \
3006+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3007+ $(call INSTALL_ITEMS, \
3008+ middle_end/flambda/base_types/*.cmi, \
3009+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3010+ $(call INSTALL_ITEMS, \
3011+ asmcomp/*.cmi, \
3012+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3013ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
3014+ $(call INSTALL_ITEMS, \
3015+ $(addprefix middle_end/, *.cmt *.cmti *.mli), \
3016+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3017+ $(call INSTALL_ITEMS, \
3018+ $(addprefix middle_end/closure/, *.cmt *.cmti *.mli), \
3019+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3020+ $(call INSTALL_ITEMS, \
3021+ $(addprefix middle_end/flambda/, *.cmt *.cmti *.mli), \
3022+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3023+ $(call INSTALL_ITEMS, \
3024+ $(addprefix middle_end/flambda/base_types/, *.cmt *.cmti *.mli), \
3025+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3026+ $(call INSTALL_ITEMS, \
3027+ $(addprefix asmcomp/, *.cmt *.cmti *.mli), \
3028+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
0000003029endif
3030+ $(call INSTALL_ITEMS, $(ocamlopt_CMO_FILES), \
3031+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
03032ifeq "$(build_ocamldoc)" "true"
3033+ $(call INSTALL_ITEMS, ocamldoc/ocamldoc.opt$(EXE), bin)
3034+ $(call INSTALL_ITEMS, \
3035+ ocamldoc/*.cmx ocamldoc/odoc_info.$(A) ocamldoc/odoc_info.cmxa, \
3036+ lib, $(INSTALL_LIBDIR_OCAMLDOC))
00000000003037endif
3038ifeq "$(strip $(NATDYNLINK))" "true"
3039+ $(call INSTALL_ITEMS, \
3040+ $(dynlink_CMX_FILES) otherlibs/dynlink/dynlink.cmxa \
3041+ otherlibs/dynlink/dynlink.$(A), \
3042+ lib, $(INSTALL_LIBDIR_DYNLINK))
3043endif
3044 for i in $(OTHERLIBS); do \
3045 $(MAKE) -C otherlibs/$$i installopt || exit $$?; \
3046 done
3047+ $(call INSTALL_ITEMS, tools/profiling.cmx tools/profiling.$(O), \
3048+ lib, $(INSTALL_LIBDIR_PROFILING))
000000000000030493050+.PHONY: full-installoptopt installopt installoptopt
3051+full-installoptopt installopt installoptopt:
3052+ $(call INSTALL_ITEM, ocamlc.opt$(EXE), bin, , , ocamlc$(EXE))
3053+ $(call INSTALL_ITEM, ocamlopt.opt$(EXE), bin, , , ocamlopt$(EXE))
3054+ $(call INSTALL_ITEM, lex/ocamllex.opt$(EXE), bin, , , ocamllex$(EXE))
00003055ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true"
3056+ $(call INSTALL_ITEM, flexlink.opt$(EXE), bin, , , flexlink$(EXE))
003057endif
3058+ $(call INSTALL_ITEMS, \
3059+ $(call COMPILER_ARTEFACT_DIRS, *.cmx, $(NATIVE_ARTEFACT_DIRS)) \
3060+ toplevel/native/tophooks.cmi, \
3061+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3062+ $(call INSTALL_ITEMS, compilerlibs/*.cmxa compilerlibs/*.$(A), \
3063+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
3064+ $(call INSTALL_ITEMS, \
3065+ $(ocamlc_CMX_FILES:.cmx=.$(O)) \
3066+ $(ocamlopt_CMX_FILES:.cmx=.$(O)) \
3067+ $(ocamlnat_CMX_FILES:.cmx=.$(O)), \
3068+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
000000003069ifeq "$(INSTALL_OCAMLNAT)" "true"
3070+ $(call INSTALL_ITEMS, ocamlnat$(EXE), bin)
3071endif
30723073# Installation of the *.ml sources of compiler-libs
3074.PHONY: install-compiler-sources
3075install-compiler-sources:
3076ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
3077+ $(call INSTALL_ITEMS, \
3078+ $(call COMPILER_ARTEFACT_DIRS, *.ml, $(NATIVE_ARTEFACT_DIRS)) \
3079+ toplevel/byte/*.ml, \
3080+ lib, $(INSTALL_LIBDIR_COMPILERLIBS))
0000003081endif
30823083include .depend
+350-15
Makefile.common
···86endif
8788DESTDIR ?=
89-INSTALL_BINDIR := $(DESTDIR)$(BINDIR)
90-INSTALL_LIBDIR := $(DESTDIR)$(LIBDIR)
91-INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml
92-INSTALL_STUBLIBDIR := $(DESTDIR)$(STUBLIBDIR)
93-INSTALL_LIBDIR_PROFILING = $(INSTALL_LIBDIR)/profiling
94-INSTALL_MANDIR := $(DESTDIR)$(MANDIR)
95-INSTALL_PROGRAMS_MAN_DIR := $(DESTDIR)$(PROGRAMS_MAN_DIR)
96-INSTALL_LIBRARIES_MAN_DIR := $(DESTDIR)$(LIBRARIES_MAN_DIR)
97-INSTALL_DOCDIR := $(DESTDIR)$(DOCDIR)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009899FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile)
100···510$(eval $(call _OCAML_NATIVE_LIBRARY,$(1)))
511endef # OCAML_LIBRARY
512513-# Installing a bytecode executable, with debug information removed
514-define INSTALL_STRIPPED_BYTE_PROG
515-$(OCAMLRUN) $(ROOTDIR)/tools/stripdebug$(EXE) $(1) $(1).tmp \
516-&& $(INSTALL_PROG) $(1).tmp $(2) \
517-&& rm $(1).tmp
518-endef # INSTALL_STRIPPED_BYTE_PROG
519520# ocamlc has several mechanisms for linking a bytecode image to the runtime
521# which executes it. The exact mechanism depends on the platform and the precise
···86endif
8788DESTDIR ?=
89+90+# Augment directories from Makefile.config / Makefile.build_config with
91+# $(DESTDIR). i.e. each of these 5 directories may be overridden by the user,
92+# and the compiler distribution makes no assumptions about where they are
93+# relative to each other.
94+INSTALL_BINDIR = $(DESTDIR)$(BINDIR)
95+INSTALL_DOCDIR = $(DESTDIR)$(DOCDIR)
96+INSTALL_LIBDIR = $(DESTDIR)$(LIBDIR)
97+INSTALL_MANDIR = $(DESTDIR)$(MANDIR)
98+INSTALL_STUBLIBDIR = $(DESTDIR)$(STUBLIBDIR)
99+100+# Library subdirectories. The compiler distribution does make assumptions about
101+# these, and they cannot be freely overridden by the user.
102+INSTALL_LIBDIR_CAML = caml
103+INSTALL_LIBDIR_COMPILERLIBS = compiler-libs
104+INSTALL_LIBDIR_DYNLINK = dynlink
105+INSTALL_LIBDIR_FLEXDLL = flexdll
106+INSTALL_LIBDIR_OCAMLDOC = ocamldoc
107+INSTALL_LIBDIR_PROFILING = profiling
108+INSTALL_LIBDIR_STDLIB = stdlib
109+INSTALL_LIBDIR_SYSTHREADS = threads
110+111+INSTALL_MANDIR_PROGRAMS = man1
112+INSTALL_MANDIR_LIBRARIES = man3
113+114+INSTALL_MODE ?= install
115+116+# The scripts and commands generated by this installation system allow the user
117+# to be installing OCaml to any kind of tortuously difficult path they choose,
118+# but it is written assuming that the directory and file names which the
119+# distribution is in control of will follow some more restrictive rules, for
120+# simplicity.
121+# Paths in the installation system should always use forward slashes (these will
122+# be automatically translated to backslashes on Windows where required). Both
123+# the single and double quote characters are prohibited in all names and paths
124+# (this vastly simplifies the quoting assumptions between Unix/Windows). The @
125+# symbol is not permitted in directory names because it used internally in
126+# filename mangling to represent forward slashes; it is permitted in filenames.
127+# Principally owing to escaping limitations of GNU make, it is not possible to
128+# use spaces in either source or target file names or in subdirectory names.
129+# tools/opam/generate.ml contains some sanity checking on the paths and names
130+# generated by these macros - make INSTALL_MODE=clone install is a good
131+# confidence check that all rules have been adhered to.
132+133+# INSTALL_ITEM installs a single file, possibly with a different name and
134+# possibly creating additional symlinks/copies
135+# $1 = source file (may include directories)
136+# $2 = section (bin, doc, lib, libexec, man, stublibs)
137+# $3 = directory within section (may be empty)
138+# $4 = target basename (may be empty)
139+# $5 = additional basenames (either symlinked or copied, depending on what the
140+# platform supports)
141+# The $(origin n) dance is necessary to suppress warnings about undefined
142+# variables.
143+INSTALL_ITEM = \
144+ $(INSTALL_$(INSTALL_MODE)_PREFIX)$(call INSTALL_ENSURE_DIR,$\
145+ $(strip $(2)),$(if $(filter-out undefined,$(origin 3)),$(strip $(3))))$\
146+ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEM,$\
147+ $(strip $(1)),$\
148+ $(strip $(2)),$\
149+ $(if $(filter-out undefined,$(origin 3)),$(strip $(3))),$\
150+ $(if $(filter-out undefined,$(origin 4)),$(strip $(4))),$\
151+ $(if $(filter-out undefined,$(origin 5)),$(strip $(5))))
152+153+# INSTALL_ITEMS installs a series of files to a single directory
154+# $1 = source file(s) (may include directories and glob patterns)
155+# $2 = section (as for INSTALL_ITEM)
156+# $3 = directory within section (may be omitted)
157+# INSTALL_ITEMS is sometimes an alias for INSTALL_ITEM. For simplicity with
158+# undefined variable warnings, INSTALL_DESPATCH_foo_ITEMS is passed 5 parameters
159+# but $4 and $5 are always empty.
160+INSTALL_ITEMS = \
161+ $(INSTALL_$(INSTALL_MODE)_PREFIX)$(call INSTALL_ENSURE_DIR,$\
162+ $(strip $(2)),$(if $(filter-out undefined,$(origin 3)),$(strip $(3))))$\
163+ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEMS,$\
164+ $(strip $(1)),$\
165+ $(strip $(2)),$\
166+ $(if $(filter-out undefined,$(origin 3)),$(strip $(3))),,)
167+168+# INSTALL_ITEMS_OPT is INSTALL_ITEMS, but does nothing if the source file(s) do
169+# not exist
170+INSTALL_ITEMS_OPT = \
171+ $(if $(wildcard $(1)),$(call INSTALL_ITEMS, \
172+ $(1), $(2), $(if $(filter-out undefined,$(origin 3)), $(3))))
173+174+INSTALL_ENSURE_DIR = \
175+ $(if $(filter undefined,$(origin DIR_CREATED_$(subst exec,,$(1))_$(2))),$\
176+ $(eval DIR_CREATED_$(subst exec,,$(1))_$(2):=)$\
177+ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_MKDIR,$\
178+ $(subst exec,,$(1)),$(2)))
179+180+# INSTALL_RM takes a single argument which may include glob patterns of files to
181+# be removed when performing a physical install.
182+INSTALL_RM = $(call INSTALL_DESPATCH_$(INSTALL_MODE)_RM,$(strip $(1)))
183+184+# INSTALL_BEGIN and INSTALL_END are used in the root Makefile's install target
185+INSTALL_BEGIN = $(INSTALL_DESPATCH_$(INSTALL_MODE)_BEGIN)
186+INSTALL_END = $(INSTALL_DESPATCH_$(INSTALL_MODE)_END)
187+188+# Normal installation
189+INSTALL_CMD_bin = $(INSTALL_PROG)
190+INSTALL_CMD_doc = $(INSTALL_DATA)
191+INSTALL_CMD_lib = $(INSTALL_DATA)
192+INSTALL_CMD_libexec = $(INSTALL_PROG)
193+INSTALL_CMD_man = $(INSTALL_DATA)
194+INSTALL_CMD_stublibs = $(INSTALL_PROG)
195+196+INSTALL_SECTION_bin = $(INSTALL_BINDIR)
197+INSTALL_SECTION_doc = $(INSTALL_DOCDIR)
198+INSTALL_SECTION_lib = $(INSTALL_LIBDIR)
199+INSTALL_SECTION_libexec = $(INSTALL_LIBDIR)
200+INSTALL_SECTION_man = $(INSTALL_MANDIR)
201+INSTALL_SECTION_stublibs = $(INSTALL_STUBLIBDIR)
202+203+QUOTE_SINGLE = '$(subst ','\'',$(1))'
204+205+define NEWLINE
206+207+208+endef
209+SH_AND = && \$(NEWLINE)
210+211+INSTALL_install_PREFIX =
212+213+INSTALL_DESPATCH_install_RM = rm -f $(1)
214+215+INSTALL_DESPATCH_install_MKDIR = \
216+ $(MKDIR) $(call QUOTE_SINGLE,$(INSTALL_SECTION_$(1))$(addprefix /,$(2))) \
217+ $(SH_AND)
218+219+MK_LINK = \
220+ (cd "$(INSTALL_SECTION_$(2))$(addprefix /,$(3))" && \
221+ $(LN) $(call QUOTE_SINGLE,$(1)) $(call QUOTE_SINGLE,$(4)))
222+223+INSTALL_DESPATCH_install_ITEM = \
224+ $(INSTALL_CMD_$(2)) $(1) \
225+ $(call QUOTE_SINGLE,$\
226+ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))$(addprefix /,$(4))) \
227+ $(foreach link, $(5),$(SH_AND)$\
228+ $(call MK_LINK,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link)))
229+230+INSTALL_DESPATCH_install_ITEMS = $(INSTALL_DESPATCH_install_ITEM)
231+232+INSTALL_DESPATCH_install_BEGIN = @
233+INSTALL_DESPATCH_install_END = @
234+235+INSTALL_display_PREFIX = @
236+237+INSTALL_DESPATCH_display_RM = @
238+239+INSTALL_DESPATCH_display_MKDIR = \
240+ echo $(call QUOTE_SINGLE,$\
241+ -> MKDIR $(INSTALL_SECTION_$(1))$(addprefix /,$(2))) $(SH_AND)
242+243+MKLINK_display = \
244+ echo $(call QUOTE_SINGLE,-> LN \
245+ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$(1)) -> \
246+ $(if $(4),$(4),$(notdir $(1))))
247+248+INSTALL_DESPATCH_display_ITEM = \
249+ echo $(call QUOTE_SINGLE,-> INSTALL $(1) \
250+ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))$(addprefix /,$(4))) \
251+ $(foreach link, $(5), && \
252+ $(call MKLINK_display,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link)))
253+254+INSTALL_DESPATCH_display_ITEMS = $(INSTALL_DESPATCH_display_ITEM)
255+256+INSTALL_DESPATCH_display_BEGIN = @
257+INSTALL_DESPATCH_display_END = @
258+259+INSTALL_list_PREFIX = @
260+261+INSTALL_DESPATCH_list_RM = @
262+263+INSTALL_DESPATCH_list_MKDIR =
264+265+MKLINK_list = \
266+ echo $(call QUOTE_SINGLE,-> \
267+ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$\
268+ $(if $(4),$(4),$(notdir $(1)))))
269+270+INSTALL_DESPATCH_list_ITEM = \
271+ echo $(call QUOTE_SINGLE,-> \
272+ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$\
273+ $(if $(4),$(4),$(notdir $(1))))) \
274+ $(foreach link, $(5), && \
275+ $(call MKLINK_list,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link)))
276+277+INSTALL_DESPATCH_list_ITEMS = \
278+ $(foreach file, $(wildcard $(1)), \
279+ echo $(call QUOTE_SINGLE,-> \
280+ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$(notdir $(file)));) \
281+ true
282+283+INSTALL_DESPATCH_list_BEGIN = @
284+INSTALL_DESPATCH_list_END = @
285+286+OPAM_PACKAGE_NAME ?= ocaml-compiler
287+288+# Generate $(OPAM_PACKAGE_NAME).install and $(OPAM_PACKAGE_NAME)-fixup.sh
289+# (INSTALL_MODE=opam)
290+# opam's .install format isn't quite rich enough at present to express the
291+# installation of the compiler. In particular, we can't install the doc files to
292+# doc/ocaml using a .install and we can't create symlinks. The things which
293+# can't be handled by the .install file are dealt with by the fixup script
294+# instead.
295+296+INVOKE = $(strip $(1)) $(call QUOTE_SINGLE,$(strip $(2)))
297+ADD_LINE = $(call INVOKE, echo, $(2)) >> $(1)
298+299+# RECORD_SYMLINK_TO_INSTALL
300+# $1 = file to install, implicitly relative to $(ROOTDIR)
301+# $2 = section
302+# $3 = subdirectory within $2 (may be empty)
303+# $4 = name to install $1 (must be specified)
304+# $5 = single name of symlink
305+# If symlinks are supported, $1 is ignored and the three pieces of information
306+# are recorded in create-symlinks: the directory, implicitly relative to the
307+# prefix, in which the symlink is to be created, the source file and name of the
308+# symlink.
309+# These can then be munged to a cd + ln combination in the fixup script.
310+# If symlinks are not supported, $1 is instead used to create an additional copy
311+# of the file, using the .install file.
312+ifeq "$(firstword $(LN))" "ln"
313+RECORD_SYMLINK_TO_INSTALL = \
314+ $(call ADD_LINE, $(ROOTDIR)/create-symlinks, \
315+ $(patsubst lib%,lib,$(2))$(addprefix /,$(3)) $(4) $(5))
316+else
317+# Symlinks aren't available, so copy the file again using the target name
318+RECORD_SYMLINK_TO_INSTALL = \
319+ $(call RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL,$(1),$(2),$(3),$(5))
320+endif
321+322+# Process the arguments to pass to RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL:
323+# - Items installed to the stublibs section need to be remapped to the stublibs
324+# subdirectory of libexec (since we install to lib/ocaml/stublibs rather than
325+# opam's default lib/stublibs)
326+# - Source files must be given implicitly relative to $(ROOTDIR), so prefix with
327+# $(SUBDIR_NAME) if necessary
328+# - Items installed to the lib/libexec sections will in fact be installed to
329+# lib_root/libexec_root, so remap the installation directory to ocaml (i.e. to
330+# install to lib/ocaml rather than lib)
331+# - If no target basename has been explictly given, use the source's basename
332+RECORD_ITEM_TO_INSTALL = \
333+ $(if $(filter stublibs,$(2)),\
334+ $(call RECORD_ITEM_TO_INSTALL,$\
335+ $(1),libexec,stublibs$(addprefix /,$(3)),$(4),$(5)),\
336+ $(call RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL,$\
337+ $(addsuffix /,$(SUBDIR_NAME))$(1),$\
338+ $(2),$\
339+ $(if $(filter doc lib%,$(2)),ocaml$(addprefix /,$(3)),$(3)),$\
340+ $(if $(4),$(4),$(notdir $(1))),$\
341+ $(5)))
342+343+# All files must be explicitly installed, so evaluate the wildcards and call
344+# INSTALL_DESPATCH_opam_ITEM for each file.
345+INSTALL_EVALUATE_GLOBS = \
346+ $(foreach file, $(wildcard $(1)), \
347+ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEM,$(file),$(2),$(3));) \
348+ true
349+350+# RECORD_FILE_TO_INSTALL
351+# $1 = file to install, implicitly relative to $(ROOTDIR)
352+# $2 = bin/lib/libexec/man
353+# $3 = subdirectory within $2 (may be empty, but otherwise must end with "/")
354+# $4 = name to install $1 (must be specified)
355+# Writes an opam .install line to the section file for $(2). Each line consists
356+# of a double-quoted implicit filename relative to $(ROOTDIR) and optionally a
357+# second double-quoted implicit filename relative to the $(2) for the name to
358+# install the file under.
359+# e.g. "lex/ocamllex" {"ocamllex.byte"} or "expunge" {"ocaml/expunge"}
360+RECORD_FILE_TO_INSTALL = \
361+ $(call ADD_LINE, $(ROOTDIR)/opam-$(2), \
362+ "$(1)" $(if $(3)$(filter-out $(notdir $(1)),$(4)), {"$(3)$(4)"}))
363+364+# RECORD_FILE_TO_CLONE
365+# $1 = file to install, implicitly relative to $(ROOTDIR)
366+# $2 = subdirectory (may be empty, but otherwise must end with "/")
367+# $3 = name to install $1 (must be specified)
368+# The compiler is installed as the ocaml package in opam, but the actual files
369+# are installed from other packages (typically ocaml-compiler). For the lib
370+# directory, the lib_root and libexec_root sections allow files to be installed
371+# to lib/ocaml, but there's no equivalent mechanism for the doc directory. These
372+# files are recorded to be copied manually in the fixup script.
373+RECORD_FILE_TO_CLONE = \
374+ $(call ADD_LINE, $(ROOTDIR)/clone-$(subst /,@,$(2)), $(1) $(3))
375+376+# RECORD_opam_ITEM_TO_INSTALL despatches the processed arguments of
377+# INSTALL_DESPATCH_opam_ITEM to the appropriate RECORD_ macro.
378+RECORD_opam_ITEM_TO_INSTALL = \
379+ $(if $(filter doc,$(2)),\
380+ $(call RECORD_FILE_TO_CLONE,$(1),doc/$(3),$(4)), \
381+ $(call RECORD_FILE_TO_INSTALL,$(1),$(2),$(addsuffix /,$(3)),$(4))) \
382+ $(foreach link, $(5), && \
383+ $(call RECORD_SYMLINK_TO_INSTALL,$(1),$(2),$(3),$(4),$(link)))
384+385+INSTALL_DESPATCH_opam_ITEM = $(RECORD_ITEM_TO_INSTALL)
386+387+INSTALL_DESPATCH_opam_ITEMS = $(INSTALL_EVALUATE_GLOBS)
388+389+INSTALL_opam_PREFIX = @
390+391+INSTALL_DESPATCH_opam_RM = @
392+393+# INSTALL_MKDIR is ignored (opam creates them when executing the .install file)
394+INSTALL_DESPATCH_opam_MKDIR =
395+396+INSTALL_DESPATCH_opam_BEGIN = \
397+ rm -f opam-bin clone-* opam-lib opam-libexec opam-man create-symlinks
398+399+# Munge opam-bin, opam-lib, opam-libexec and opam-man into a .install file and
400+# then munge clone-* and create-symlinks into the fixup script.
401+INSTALL_DESPATCH_opam_END = \
402+ $(OCAMLRUN) ./ocaml$(EXE) $(STDLIBFLAGS) \
403+ tools/opam/generate.ml $(INSTALL_MODE) $(OPAM_PACKAGE_NAME) '$(LN)'
404+405+# Generate $(OPAM_PACKAGE_NAME)-clone.sh (INSTALL_MODE=clone)
406+407+# ld.conf is explicitly copied, rather than cloned, to allow (in principle, if
408+# not in practice) the cloning installation to edit it.
409+RECORD_clone_ITEM_TO_INSTALL = \
410+ $(if $(filter runtime/ld.conf Makefile.config, $(1)), true, \
411+ $(if $(filter libexec,$(2)), \
412+ $(call RECORD_clone_ITEM_TO_INSTALL,$(1),lib,$(3),$(4),$(5)), \
413+ $(call ADD_LINE, \
414+ $(ROOTDIR)/clone-$(2)$(addprefix @,$(subst /,@,$(3))), \
415+ $(2)$(addprefix /,$(3))/$(if $(4),$(4),$(notdir $(1)))) \
416+ $(foreach link, $(5), && \
417+ $(call RECORD_SYMLINK_TO_INSTALL,$(1),$(2),$(3),$(4),$(link)))))
418+419+INSTALL_DESPATCH_clone_ITEM = $(RECORD_ITEM_TO_INSTALL)
420+421+INSTALL_DESPATCH_clone_ITEMS = $(INSTALL_EVALUATE_GLOBS)
422+423+INSTALL_clone_PREFIX = @
424+425+INSTALL_DESPATCH_clone_RM = @
426+427+# INSTALL_MKDIR is ignored - INSTALL_DESPATCH_clone_END automatically creates
428+# directories for each cp file.
429+INSTALL_DESPATCH_clone_MKDIR =
430+431+INSTALL_DESPATCH_clone_BEGIN = rm -f clone-* create-symlinks
432+433+INSTALL_DESPATCH_clone_END = $(INSTALL_DESPATCH_opam_END)
434435FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile)
436···846$(eval $(call _OCAML_NATIVE_LIBRARY,$(1)))
847endef # OCAML_LIBRARY
848849+# Strip debug information from a bytecode executable
850+define STRIP_BYTE_PROG
851+$(OCAMLRUN) $(ROOTDIR)/tools/stripdebug$(EXE) \
852+ $(strip $(1)) $(strip $(1)).stripped
853+endef # STRIP_BYTE_PROG
0854855# ocamlc has several mechanisms for linking a bytecode image to the runtime
856# which executes it. The exact mechanism depends on the platform and the precise
+1
api_docgen/Makefile
···14#**************************************************************************
15# Used by included Makefiles
16ROOTDIR = ..
017-include ../Makefile.build_config
1819odoc-%:
···14#**************************************************************************
15# Used by included Makefiles
16ROOTDIR = ..
17+SUBDIR_NAME = api_docgen
18-include ../Makefile.build_config
1920odoc-%:
+2-4
api_docgen/ocamldoc/Makefile
···14#**************************************************************************
15# Used by included Makefiles
16ROOTDIR = ../..
017include ../Makefile.common
18vpath %.mli ../../stdlib $(DOC_COMPILERLIBS_DIRS) $(DOC_STDLIB_DIRS)
19···121122.PHONY: install
123install:
124- $(MKDIR) "$(INSTALL_LIBRARIES_MAN_DIR)"
125- if test -d build/man; then \
126- $(INSTALL_DATA) build/man/*.3o "$(INSTALL_LIBRARIES_MAN_DIR)"; \
127- fi
···14#**************************************************************************
15# Used by included Makefiles
16ROOTDIR = ../..
17+SUBDIR_NAME = api_docgen/ocamldoc
18include ../Makefile.common
19vpath %.mli ../../stdlib $(DOC_COMPILERLIBS_DIRS) $(DOC_STDLIB_DIRS)
20···122123.PHONY: install
124install:
125+ $(call INSTALL_ITEMS_OPT, build/man/*.3o, man, $(INSTALL_MANDIR_LIBRARIES))
000
+5-7
api_docgen/odoc/Makefile
···1516# Used by included Makefiles
17ROOTDIR = ../..
01819include ../Makefile.common
20···191# Man pages are the only installed documentation
192.PHONY: install
193install:
194- $(MKDIR) "$(INSTALL_LIBRARIES_MAN_DIR)"
195- if test -d build/man/libref ; then \
196- $(INSTALL_DATA) build/man/libref/* "$(INSTALL_LIBRARIES_MAN_DIR)"; \
197- fi
198- if test -d build/man/compilerlibref ; then \
199- $(INSTALL_DATA) build/man/libref/* "$(INSTALL_LIBRARIES_MAN_DIR)"; \
200- fi
201202# Dependencies for stdlib modules.
203# Use the same dependencies used for compiling .cmx files.
···1516# Used by included Makefiles
17ROOTDIR = ../..
18+SUBDIR_NAME = api_docgen/odoc
1920include ../Makefile.common
21···192# Man pages are the only installed documentation
193.PHONY: install
194install:
195+ $(call INSTALL_ITEMS_OPT, \
196+ build/man/libref/*, man, $(INSTALL_MANDIR_LIBRARIES))
197+ $(call INSTALL_ITEMS_OPT, \
198+ build/man/compilerlibref/*, man, $(INSTALL_MANDIR_LIBRARIES))
000199200# Dependencies for stdlib modules.
201# Use the same dependencies used for compiling .cmx files.
···14#**************************************************************************
1516ROOTDIR=..
017include $(ROOTDIR)/Makefile.common
1819# Although the OTHERLIBS variable is defined in ../Makefile.config,
···14#**************************************************************************
1516ROOTDIR=..
17+SUBDIR_NAME=otherlibs
18include $(ROOTDIR)/Makefile.common
1920# Although the OTHERLIBS variable is defined in ../Makefile.config,
+23-30
otherlibs/Makefile.otherlibs.common
···16# Common Makefile for otherlibs
1718ROOTDIR=../..
019include $(ROOTDIR)/Makefile.common
20include $(ROOTDIR)/Makefile.best_binaries
21···109lib$(CLIBNAME_NATIVE).$(A): $(COBJS)
110 $(V_OCAMLMKLIB)$(MKLIB) -oc $(CLIBNAME_NATIVE) $(COBJS_NATIVE) $(LDOPTS)
111112-INSTALL_LIBDIR_LIBNAME = $(INSTALL_LIBDIR)/$(LIBNAME)
113-114install::
115ifneq "$(STUBSLIB_BYTECODE)" ""
116ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true"
117- $(INSTALL_PROG) $(STUBSDLL) "$(INSTALL_STUBLIBDIR)"
118endif
119- $(INSTALL_DATA) $(STUBSLIB_BYTECODE) "$(INSTALL_LIBDIR)/"
120endif
121# If installing over a previous OCaml version, ensure the library is removed
122# from the previous installation.
123- rm -f $(addprefix "$(INSTALL_LIBDIR)"/, \
124- $(LIBNAME).cma $(CMIFILES) \
125- $(CMIFILES:.cmi=.mli) $(CMIFILES:.cmi=.cmti) \
126- $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).cmxs $(LIBNAME).$(A))
127- $(MKDIR) "$(INSTALL_LIBDIR_LIBNAME)"
128- $(INSTALL_DATA) \
129- $(LIBNAME).cma $(CMIFILES) META \
130- "$(INSTALL_LIBDIR_LIBNAME)/"
131ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
132- $(INSTALL_DATA) \
133- $(CMIFILES:.cmi=.mli) \
134- $(CMIFILES:.cmi=.cmti) \
135- "$(INSTALL_LIBDIR_LIBNAME)/"
136endif
137- if test -n "$(HEADERS)"; then \
138- $(INSTALL_DATA) $(HEADERS) "$(INSTALL_INCDIR)/"; \
139- fi
140141installopt:
142- $(INSTALL_DATA) \
143- $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).$(A) \
144- "$(INSTALL_LIBDIR_LIBNAME)/"
145- if test -f $(LIBNAME).cmxs; then \
146- $(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR_LIBNAME)"; \
147- fi
148- if test -f dll$(CLIBNAME_NATIVE)$(EXT_DLL); then \
149- $(INSTALL_PROG) \
150- dll$(CLIBNAME_NATIVE)$(EXT_DLL) "$(INSTALL_STUBLIBDIR)"; \
151- fi
152ifneq "$(STUBSLIB_NATIVE)" ""
153- $(INSTALL_DATA) $(STUBSLIB_NATIVE) "$(INSTALL_LIBDIR)/"
154endif
155156partialclean:
···14#**************************************************************************
1516ROOTDIR = ..
017# NOTE: it is important that the OCAMLDEP variable is defined *before*
18# Makefile.common gets included, so that its local definition here
19# take precedence over its general shared definitions in Makefile.common.
···47OPTCOMPILER=$(ROOTDIR)/ocamlopt$(EXE)
48CAMLOPT=$(OCAMLRUN) $(OPTCOMPILER)
4900050include StdlibModules
5152OBJS=$(addsuffix .cmo,$(STDLIB_MODULES))
···60allopt: stdlib.cmxa std_exit.cmx
61opt.opt: allopt
6263-INSTALL_STDLIB_META_DIR=$(DESTDIR)$(LIBDIR)/stdlib
64-65.PHONY: install
66install::
67- $(INSTALL_DATA) \
68- stdlib.cma std_exit.cmo *.cmi "$(INSTALL_LIBDIR)"
69- $(MKDIR) "$(INSTALL_STDLIB_META_DIR)"
70- $(INSTALL_DATA) META "$(INSTALL_STDLIB_META_DIR)"
71ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
72- $(INSTALL_DATA) \
73- *.cmt *.cmti *.mli *.ml *.ml.in \
74- "$(INSTALL_LIBDIR)"
75endif
76- $(INSTALL_DATA) $(HEADER_NAME) "$(INSTALL_LIBDIR)/$(HEADER_NAME)"
7778.PHONY: installopt
79installopt: installopt-default
8081.PHONY: installopt-default
82installopt-default:
83- $(INSTALL_DATA) \
84- stdlib.cmxa stdlib.$(A) std_exit.$(O) *.cmx \
85- "$(INSTALL_LIBDIR)"
8687MANGLING = $(filter true,$(SUFFIXING))
88runtime-launch-info: tmpheader.exe
···14#**************************************************************************
1516ROOTDIR = ..
17+SUBDIR_NAME = stdlib
18# NOTE: it is important that the OCAMLDEP variable is defined *before*
19# Makefile.common gets included, so that its local definition here
20# take precedence over its general shared definitions in Makefile.common.
···48OPTCOMPILER=$(ROOTDIR)/ocamlopt$(EXE)
49CAMLOPT=$(OCAMLRUN) $(OPTCOMPILER)
5051+# At present, only META is installed to the package directory
52+LIBNAME = stdlib
53+54include StdlibModules
5556OBJS=$(addsuffix .cmo,$(STDLIB_MODULES))
···64allopt: stdlib.cmxa std_exit.cmx
65opt.opt: allopt
660067.PHONY: install
68install::
69+ $(call INSTALL_ITEMS, stdlib.cma std_exit.cmo *.cmi, lib)
70+ $(call INSTALL_ITEMS, META, lib, $(LIBNAME))
0071ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
72+ $(call INSTALL_ITEMS, *.cmt *.cmti *.mli *.ml *.ml.in, lib)
0073endif
74+ $(call INSTALL_ITEMS, $(HEADER_NAME), lib)
7576.PHONY: installopt
77installopt: installopt-default
7879.PHONY: installopt-default
80installopt-default:
81+ $(call INSTALL_ITEMS, stdlib.cmxa stdlib.$(A) std_exit.$(O) *.cmx, lib)
008283MANGLING = $(filter true,$(SUFFIXING))
84runtime-launch-info: tmpheader.exe
+47-5
tools/ci/actions/runner.sh
···1617set -xe
1819-PREFIX=~/local
02021MAKE="make $MAKE_ARG"
22SHELL=dash
···56 # $CONFIG_ARG also appears last to allow settings specified here to be
57 # overridden by the workflows.
58 call-configure --prefix="$PREFIX" \
059 --enable-flambda-invariants \
60 --enable-ocamltest \
61 --enable-native-toplevel \
62 --disable-dependency-generation \
63- $CONFIG_ARG
64}
6566Build () {
···125}
126127Install () {
128- $MAKE install
0000000000000000000129}
130131target_libdir_is_relative='^ *TARGET_LIBDIR_IS_RELATIVE *= *false'
···225 # we would need to redo (small parts of) world.opt afterwards to
226 # use the compiler again
227 $MAKE check_all_arches
228- # Ensure that .gitignore is up-to-date - this will fail if any untreacked or
229 # altered files exist.
230 test -z "$(git status --porcelain)"
231 # check that the 'clean' target also works
···234 $MAKE -C manual distclean
235 # check that the `distclean` target definitely cleans the tree
236 $MAKE distclean
237- # Check the working tree is clean
00238 test -z "$(git status --porcelain)"
239 # Check that there are no ignored files
240 test -z "$(git ls-files --others -i --exclude-standard)"
···298 ReportBuildStatus 0
299}
300000000000000000000301case $1 in
302configure) Configure;;
303build) Build;;
···311manual) BuildManual;;
312other-checks) Checks;;
313basic-compiler) BasicCompiler;;
0314*) echo "Unknown CI instruction: $1"
315 exit 1;;
316esac
···1617set -xe
1819+# The prefix is designed to be usable as an opam local switch
20+PREFIX=~/local/_opam
2122MAKE="make $MAKE_ARG"
23SHELL=dash
···57 # $CONFIG_ARG also appears last to allow settings specified here to be
58 # overridden by the workflows.
59 call-configure --prefix="$PREFIX" \
60+ --docdir="$PREFIX/doc/ocaml" \
61 --enable-flambda-invariants \
62 --enable-ocamltest \
63 --enable-native-toplevel \
64 --disable-dependency-generation \
65+ -C $CONFIG_ARG
66}
6768Build () {
···127}
128129Install () {
130+ $MAKE INSTALL_MODE=list install | grep '^->' | sort | uniq -d > duplicates
131+ if [ -s duplicates ]; then
132+ echo "The installation duplicates targets:"
133+ cat duplicates
134+ exit 1
135+ fi
136+ rm duplicates
137+ $MAKE DESTDIR="$PWD/install" install
138+ find $PWD/install -name _opam -type d
139+ $MAKE INSTALL_MODE=clone install
140+ ret="$PWD"
141+ script="$PWD/ocaml-compiler-clone.sh"
142+ cd "$(find $PWD/install -name _opam -type d)"
143+ mkdir -p "share/ocaml"
144+ cp "$ret/config.status" "$ret/config.cache" "share/ocaml"
145+ cp "$ret/ocaml-compiler-clone.sh" "share/ocaml/clone"
146+ sh $script ~/local/_opam
147+ cd "$ret"
148+ rm -rf install
149+ rm ocaml-compiler-clone.sh
150}
151152target_libdir_is_relative='^ *TARGET_LIBDIR_IS_RELATIVE *= *false'
···246 # we would need to redo (small parts of) world.opt afterwards to
247 # use the compiler again
248 $MAKE check_all_arches
249+ # Ensure that .gitignore is up-to-date - this will fail if any untracked or
250 # altered files exist.
251 test -z "$(git status --porcelain)"
252 # check that the 'clean' target also works
···255 $MAKE -C manual distclean
256 # check that the `distclean` target definitely cleans the tree
257 $MAKE distclean
258+ # Check the working tree is clean - config.cache is intentionally not deleted
259+ # by any of the clean targets
260+ rm config.cache
261 test -z "$(git status --porcelain)"
262 # Check that there are no ignored files
263 test -z "$(git ls-files --others -i --exclude-standard)"
···321 ReportBuildStatus 0
322}
323324+CreateSwitch () {
325+ # This can be switched to use the Ubuntu package when Ubuntu 26.04 is deployed
326+ # (opam 2.1.5 in Ubuntu 24.04 is too old)
327+ curl -Lo opam \
328+ 'https://github.com/ocaml/opam/releases/download/2.4.1/opam-2.4.1-x86_64-linux'
329+ chmod +x opam
330+ ./opam init --cli=2.4 --bare --disable-sandboxing --yes --auto-setup
331+ # This is intentionally done before the switch is created - if the install
332+ # target creates _opam then the switch creation will fail.
333+ $MAKE INSTALL_MODE=opam OPAM_PACKAGE_NAME=ocaml-variants install
334+ # These commands intentionally run using opam's "default" CLI
335+ ./opam switch create ~/local --empty
336+ ./opam switch --switch ~/local set-invariant --no-action ocaml-option-flambda
337+ ./opam pin add --switch ~/local --no-action --kind=path ocaml-variants .
338+ ./opam install --switch ~/local --yes --assume-built ocaml-variants
339+ ./opam exec --switch ~/local -- ocamlopt -v
340+}
341+342case $1 in
343configure) Configure;;
344build) Build;;
···352manual) BuildManual;;
353other-checks) Checks;;
354basic-compiler) BasicCompiler;;
355+opam) CreateSwitch;;
356*) echo "Unknown CI instruction: $1"
357 exit 1;;
358esac
+18-4
tools/ci/appveyor/appveyor_build.cmd
···2223chcp 65001 > nul
24set BUILD_PREFIX=🐫реализация
25-set OCAMLROOT=%PROGRAMFILES%\Бактріан🐫
2627if "%1" neq "install" goto %1
28setlocal enabledelayedexpansion
···69 )
70)
71if "%CYGWIN_INSTALL_PACKAGES%" neq "" "%CYG_ROOT%\setup-x86_64.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" %CYGWIN_FLAGS% --packages %CYGWIN_INSTALL_PACKAGES:~1%
72-for %%P in (%CYGWIN_COMMANDS%) do "%CYG_ROOT%\bin\%%P.exe" --version 2> nul > nul || set CYGWIN_UPGRADE_REQUIRED=1
00000073"%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%"
74if %CYGWIN_UPGRADE_REQUIRED% equ 1 (
75 echo Cygwin package upgrade required - please go and drink coffee
···87 if "%PORT%" equ "mingw32" set SDK=call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat"
88)
89%SDK%
0000090goto :EOF
9192:install
···103cd "%APPVEYOR_BUILD_FOLDER%"
104appveyor DownloadFile "https://github.com/ocaml/flexdll/archive/%FLEXDLL_VERSION%.tar.gz" -FileName "flexdll.tar.gz" || exit /b 1
105appveyor DownloadFile "https://github.com/ocaml/flexdll/releases/download/%FLEXDLL_VERSION%/flexdll-bin-%FLEXDLL_VERSION%.zip" -FileName "flexdll.zip" || exit /b 1
000106rem flexdll.zip is processed here, rather than in appveyor_build.sh because the
107rem unzip command comes from MSYS2 (via Git for Windows) and it has to be
108rem invoked via cmd /c in a bash script which is weird(er).
···115rem CYGWIN_COMMANDS is a corresponding command to run with --version to test
116rem whether the package works. This is used to verify whether the installation
117rem needs upgrading.
118-set CYGWIN_PACKAGES=cygwin make diffutils
119-set CYGWIN_COMMANDS=cygcheck make diff
120if "%PORT%" equ "mingw32" (
121 rem mingw64-i686-runtime does not need explicitly installing, but it's useful
122 rem to have the version reported.
···2223chcp 65001 > nul
24set BUILD_PREFIX=🐫реализация
25+set OCAMLROOT=C:\Бактріан🐫
2627if "%1" neq "install" goto %1
28setlocal enabledelayedexpansion
···69 )
70)
71if "%CYGWIN_INSTALL_PACKAGES%" neq "" "%CYG_ROOT%\setup-x86_64.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" %CYGWIN_FLAGS% --packages %CYGWIN_INSTALL_PACKAGES:~1%
72+for %%P in (%CYGWIN_COMMANDS%) do (
73+ if %%P equ unzip (
74+ "%CYG_ROOT%\bin\%%P.exe" -v 2> nul > nul || set CYGWIN_UPGRADE_REQUIRED=1
75+ ) else (
76+ "%CYG_ROOT%\bin\%%P.exe" --version 2> nul > nul || set CYGWIN_UPGRADE_REQUIRED=1
77+ )
78+)
79"%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%"
80if %CYGWIN_UPGRADE_REQUIRED% equ 1 (
81 echo Cygwin package upgrade required - please go and drink coffee
···93 if "%PORT%" equ "mingw32" set SDK=call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat"
94)
95%SDK%
96+rem The environment block becomes very large on AppVeyor, which can cause
97+rem problems for xargs in Cygwin. These two environment variables from the SDK
98+rem infrastructure can be safely junked to reduce the size of the block.
99+set __VSCMD_PREINIT_PATH=
100+set EXTERNAL_INCLUDE=
101goto :EOF
102103:install
···114cd "%APPVEYOR_BUILD_FOLDER%"
115appveyor DownloadFile "https://github.com/ocaml/flexdll/archive/%FLEXDLL_VERSION%.tar.gz" -FileName "flexdll.tar.gz" || exit /b 1
116appveyor DownloadFile "https://github.com/ocaml/flexdll/releases/download/%FLEXDLL_VERSION%/flexdll-bin-%FLEXDLL_VERSION%.zip" -FileName "flexdll.zip" || exit /b 1
117+appveyor DownloadFile "https://github.com/ocaml/opam/releases/download/2.4.1/opam-2.4.1-x86_64-windows.exe" -FileName "opam.exe" || exit /b 1
118+md "%PROGRAMFILES%\flexdll"
119+move opam.exe "%PROGRAMFILES%\flexdll"
120rem flexdll.zip is processed here, rather than in appveyor_build.sh because the
121rem unzip command comes from MSYS2 (via Git for Windows) and it has to be
122rem invoked via cmd /c in a bash script which is weird(er).
···129rem CYGWIN_COMMANDS is a corresponding command to run with --version to test
130rem whether the package works. This is used to verify whether the installation
131rem needs upgrading.
132+set CYGWIN_PACKAGES=cygwin make diffutils unzip
133+set CYGWIN_COMMANDS=cygcheck make diff unzip
134if "%PORT%" equ "mingw32" (
135 rem mingw64-i686-runtime does not need explicitly installing, but it's useful
136 rem to have the version reported.
+39-1
tools/ci/appveyor/appveyor_build.sh
···59 CACHE_FILE_PREFIX="$CACHE_DIRECTORY/config.cache-$1"
60 CACHE_FILE="$CACHE_FILE_PREFIX-$CACHE_KEY"
6162- args=('--cache-file' "$CACHE_FILE" '--prefix' "$2" '--enable-ocamltest')
0006364 case "$1" in
65 cygwin*)
···96 if ((failed)) ; then cat config.log ; exit $failed ; fi
97 fi
980099# FILE=$(pwd | cygpath -f - -m)/Makefile.config
100# run "Content of $FILE" cat Makefile.config
101}
···103PARALLEL_URL='https://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel'
104APPVEYOR_BUILD_FOLDER=$(echo "$APPVEYOR_BUILD_FOLDER" | cygpath -f -)
105FLEXDLLROOT="$PROGRAMFILES/flexdll"
0106107if [[ $BOOTSTRAP_FLEXDLL = 'false' ]] ; then
108 case "$PORT" in
···177 make -C "$FULL_BUILD_PREFIX-$PORT/testsuite" SHOW_TIMINGS=1 all
178 fi
179 run "install $PORT" $MAKE -C "$FULL_BUILD_PREFIX-$PORT" install
00000000000000000000000000000000180 run "test $PORT in prefix" \
181 $MAKE -f Makefile.test -C "$FULL_BUILD_PREFIX-$PORT/testsuite/in_prefix" \
182 test-in-prefix
···1+(**************************************************************************)
2+(* *)
3+(* OCaml *)
4+(* *)
5+(* David Allsopp, University of Cambridge & Tarides *)
6+(* *)
7+(* Copyright 2025 David Allsopp Ltd. *)
8+(* *)
9+(* All rights reserved. This file is distributed under the terms of *)
10+(* the GNU Lesser General Public License version 2.1, with the *)
11+(* special exception on linking described in the file LICENSE. *)
12+(* *)
13+(**************************************************************************)
14+15+(* This script is called from the root of the repository at the end of
16+ `make INSTALL_MODE=<opam|clone> install` and is responsible for converting
17+ the various files generated by the installation backend into final output.
18+ Parameters are the following Makefile variables:
19+ $1 = $(INSTALL_MODE) (opam or clone)
20+ $2 = $(OPAM_PACKAGE_NAME)
21+ $3 = $(LN) *)
22+23+let exit_because fmt = Printf.ksprintf (fun s -> prerr_endline s; exit 1) fmt
24+25+let () =
26+ if Array.length Sys.argv <> 4
27+ || Sys.argv.(1) <> "clone" && Sys.argv.(1) <> "opam" then begin
28+ exit_because "Invalid command line arguments"
29+ end
30+31+let mode = Sys.argv.(1)
32+let package = Sys.argv.(2)
33+let ln_command = Sys.argv.(3)
34+35+let output_endline oc = Printf.kfprintf (fun oc -> output_char oc '\n') oc
36+37+let write_install_lines oc file =
38+ In_channel.with_open_text file @@
39+ In_channel.fold_lines (fun _ -> output_endline oc " %s") ()
40+41+let remove_file = Sys.remove
42+43+let output_section oc section =
44+ let file = "opam-" ^ section in
45+ if Sys.file_exists file then begin
46+ let section =
47+ if section = "lib" || section = "libexec" then
48+ section ^ "_root"
49+ else
50+ section
51+ in
52+ output_endline oc {|%s: [
53+%a]|} section write_install_lines file;
54+ remove_file file
55+ end
56+57+(* See note in Makefile.common *)
58+let valid_in_path = function '\'' | '"' | '\\' -> false | _ -> true
59+let valid_in_section c = c <> '@' && valid_in_path c
60+let valid_path path =
61+ if String.for_all valid_in_path path then
62+ path
63+ else
64+ exit_because "%S contains characters invalid in a path" path
65+let valid_section dir =
66+ if String.for_all valid_in_section dir then
67+ dir
68+ else
69+ exit_because "%S contains characters invalid in a section" dir
70+71+(* [generate_install file] processes then erases opam-bin, opam-lib opam-libexec
72+ and opam-man to produce [file] *)
73+let generate_install file =
74+ Out_channel.with_open_text file @@ fun oc ->
75+ List.iter (output_section oc) ["bin"; "lib"; "libexec"; "man"];
76+ output_endline oc {|share_root: [
77+ "config.cache" {"ocaml/config.cache"}
78+ "config.status" {"ocaml/config.status"}
79+]|}
80+81+(* [process_clone oc process] processes clone-* in the current directory,
82+ emitting mkdir commands to [oc] and passing the directory name and a channel
83+ set to the start of each clone file to [process]. The clone files are erased
84+ after processing. *)
85+let process_clone oc process =
86+ let process_file file =
87+ if String.starts_with ~prefix:"clone-" file then begin
88+ let dir =
89+ String.map (function '@' -> '/' | c -> c)
90+ (String.sub file 6 (String.length file - 6))
91+ |> valid_section
92+ in
93+ output_endline oc {|mkdir -p "$1"'/%s'|} dir;
94+ In_channel.with_open_text file @@ process oc dir;
95+ remove_file file
96+ end
97+ in
98+ let files = Sys.readdir Filename.current_dir_name in
99+ Array.sort String.compare files;
100+ Array.iter process_file files
101+102+(* [process_symlinks oc ~mkdir] processes create-symlinks, if it exists, writing
103+ any required mkdir commands to [oc] if [~mkdir = true] and also the
104+ appropriate ln / mklink commands. create-symlinks is erased after
105+ processing. *)
106+let process_symlinks oc ~mkdir =
107+ let module StringSet = Set.Make(String) in
108+ let file = "create-symlinks" in
109+ if Sys.file_exists file then
110+ let lines =
111+ let parse acc line =
112+ match String.split_on_char ' ' line with
113+ | [dir; target; source] ->
114+ (valid_section dir, valid_path target, valid_path source)::acc
115+ | _ ->
116+ exit_because "Invalid line encountered in create-symlinks"
117+ in
118+ In_channel.with_open_text file @@ fun ic ->
119+ List.rev (In_channel.fold_lines parse [] ic)
120+ in
121+ output_endline oc {|cd "$1"|};
122+ let _ =
123+ let create_dir seen (dir, _, _) =
124+ if not (StringSet.mem dir seen) && String.contains dir '/' then
125+ output_endline oc {|mkdir -p '%s'|} dir;
126+ StringSet.add dir seen
127+ in
128+ List.fold_left create_dir StringSet.empty (if mkdir then lines else [])
129+ in
130+ if not Sys.win32 then
131+ let ln (dir, target, source) =
132+ output_endline oc {|%s '%s' '%s/%s'|} ln_command target dir source
133+ in
134+ List.iter ln lines
135+ else begin
136+ let mklink (dir, target, source) =
137+ (* Convert all slashes to _two_ backslashes *)
138+ let to_backslashes oc s =
139+ output_string oc (String.concat {|\\|} (String.split_on_char '/' s))
140+ in
141+ output_endline oc
142+ {| cmd /c "mklink %a\\%s %s"|} to_backslashes dir source target
143+ and cp (dir, target, source) =
144+ output_endline oc {| $CP '%s/%s' '%s/%s'|} dir target dir source
145+ in
146+ output_endline oc {|cmd /c "mklink __ln_test mklink-test"|};
147+ output_endline oc {|if test -L "$1/__ln_test"; then|};
148+ List.iter mklink lines;
149+ output_endline oc {|else|};
150+ List.iter cp lines;
151+ output_endline oc {|fi|};
152+ output_endline oc {|rm -f __ln_test|}
153+ end;
154+ remove_file file
155+156+let copy_files oc dir =
157+ In_channel.fold_lines (fun _ line ->
158+ match String.split_on_char ' ' line with
159+ | [source; dest] ->
160+ let source = valid_path source in
161+ let dest = valid_path dest in
162+ output_endline oc {|cp '%s' "$1"'/%s/%s'|} source dir dest
163+ | _ ->
164+ exit_because "Invalid line encountered in clone files") ()
165+166+let clone_files oc dir ic =
167+ output_endline oc
168+ {|dest="$1"'/%s' xargs sh "$1/clone-files" <<'EOF'|} dir;
169+ In_channel.fold_lines (fun _ -> output_endline oc "%s") () ic;
170+ output_endline oc {|EOF|}
171+172+let () =
173+ if mode = "opam" then begin
174+ generate_install (package ^ ".install");
175+ (* The script must be written with Unix line-endings on Windows *)
176+ Out_channel.with_open_bin (package ^ "-fixup.sh") @@ fun oc ->
177+ output_endline oc {|#!/bin/sh
178+set -eu|};
179+ process_clone oc copy_files;
180+ process_symlinks oc ~mkdir:true
181+ end else begin
182+ (* Don't pass -p to cp on Windows - it's never going to be relevant (no
183+ execute bit which needs preserving) and there are scenarios in which it's
184+ more likely to fail than add anything useful (especially if copying from
185+ a Cygwin-managed build directory to /cygdrive) *)
186+ let preserve = if Sys.win32 then "" else "p" in
187+ (* The script must be written with Unix line-endings on Windows *)
188+ Out_channel.with_open_bin (package ^ "-clone.sh") @@ fun oc ->
189+ output_endline oc {|#!/bin/sh
190+set -eu
191+mkdir -p "$1"
192+rm -f "$1/__cp_test" "$1/__ln_test"
193+if cp --reflink=always doc/ocaml/LICENSE "$1/__cp_test" 2>/dev/null; then
194+ rm -f "$1/__cp_test"
195+ CP='cp --reflink=always -%sf'
196+ if ! test -e "$1/clone-files"; then
197+ echo "$CP"' "$@" "$dest/"' > "$1/clone-files"
198+ fi
199+else
200+ CP='cp -%sf'
201+ if ! test -e "$1/clone-files"; then
202+ if ln -f doc/ocaml/LICENSE "$1/__ln_test" 2>/dev/null; then
203+ rm -f "$1/__ln_test"
204+ echo 'ln -f "$@" "$dest/"' > "$1/clone-files"
205+ else
206+ echo "$CP"' "$@" "$dest/"' > "$1/clone-files"
207+ fi
208+ fi
209+fi|} preserve preserve;
210+ Out_channel.with_open_text "clone-share@ocaml" (fun oc ->
211+ output_endline oc "share/ocaml/clone";
212+ if Sys.file_exists "config.cache" then
213+ output_endline oc "share/ocaml/config.cache");
214+ process_clone oc clone_files;
215+ (* ld.conf is a configuration file, so is always copied.
216+ Makefile.config and config.status will both contain the original
217+ prefix, which must be updated. *)
218+ output_endline oc {|cp lib/ocaml/ld.conf "$1/lib/ocaml/ld.conf"
219+cat > "$1/prefix.awk" <<'ENDAWK'
220+{
221+ rest = $0
222+ while ((p = index(rest, ENVIRON["O"]))) {
223+ printf "%%s%%s", substr(rest, 1, p-1), ENVIRON["N"]
224+ rest = substr(rest, p + length(ENVIRON["O"]))
225+ }
226+ print rest
227+}
228+ENDAWK
229+prefix="$(sed -ne 's/^prefix *= *//p' lib/ocaml/Makefile.config)"
230+for file in lib/ocaml/Makefile.config share/ocaml/config.status; do
231+ O="$prefix" N="$1" awk -f "$1/prefix.awk" "$file" > "$1/$file"
232+done
233+rm -f "$1/clone-files" "$1/prefix.awk"|};
234+ process_symlinks oc ~mkdir:false
235+ end
···1+#!/bin/sh
2+#**************************************************************************
3+#* *
4+#* OCaml *
5+#* *
6+#* David Allsopp, University of Cambridge & Tarides *
7+#* *
8+#* Copyright 2025 David Allsopp Ltd. *
9+#* *
10+#* All rights reserved. This file is distributed under the terms of *
11+#* the GNU Lesser General Public License version 2.1, with the *
12+#* special exception on linking described in the file LICENSE. *
13+#* *
14+#**************************************************************************
15+16+set -eu
17+18+# POSIX.1-2024 (Issue 8) lifts this from being a bashism. The sub-shell dance is
19+# necessary because set is a builtin and is permitted to abort the script
20+# unconditionally on error.
21+if (set -o pipefail 2> /dev/null); then
22+ set -o pipefail
23+fi
24+25+# This script is responsible for building and cloning OCaml installations. It is
26+# invoked by both the build and install sections of an opam package.
27+# $1 = make command (the `make` variable in opam). This should be the path to
28+# a binary only and is invoked without word-splitting (i.e. any
29+# additional arguments should be passed in $2 and the command is invoked
30+# "$1").
31+# $2 = additional arguments passed to "$1". This variable will be used
32+# unquoted - arguments with spaces cannot be passed. From the build
33+# section, this allows the -j argument to be specified. For the install
34+# section, this argument must be "install".
35+# $3 = opam build-id variable of this package.
36+# $4 = name of the opam package to be used when generating .install and
37+# .config files.
38+# The remaining arguments depend on the value of $2. When it is "install":
39+# $5 = installation prefix, which may be a native Windows path, rather than a
40+# Cygwin path.
41+# When $2 is not "install" (the build opam section):
42+# $5 = "enabled" if cloning the compiler from an existing switch is permitted
43+# and "disabled" to force the compiler to be built from sources.
44+# $6, and any further arguments are additional options to pass to `configure`
45+# if the compiler is built from sources.
46+47+make="$1"
48+make_args="$2"
49+build_id="$3"
50+package_name="$4"
51+52+if [ x"$make_args" = 'xinstall' ]; then
53+ prefix="$5"
54+55+ echo "📦 Installing the compiler to $prefix"
56+ if [ -e 'config.status' ]; then
57+ echo "📜 Using make install"
58+ "$make" install
59+ else
60+ origin="$(tail -n 1 build-id)"
61+ origin_prefix="$(opam var --safe --switch="$origin" prefix | tr -d '\r')"
62+ echo "🪄 Duplicating $origin_prefix"
63+ ( cd "$origin_prefix" && sh ./share/ocaml/clone "$prefix" )
64+ fi
65+66+ exit 0
67+fi
68+69+# Build the package
70+71+cloning="$5"
72+shift 5
73+# "$@" now expands to the correctly-quoted arguments to pass to configure
74+75+origin=''
76+clone_mechanism=''
77+if [ x"$cloning" = 'xenabled' ]; then
78+ echo "🕵️ Searching for a switch containing build-id $build_id"
79+80+ if [ -e "$OPAM_SWITCH_PREFIX/share/ocaml/build-id" ]; then
81+ switch="$(tail -n 1 "$OPAM_SWITCH_PREFIX/share/ocaml/build-id")"
82+ if [ -n "$switch" ]; then
83+ switch_share_dir="$(opam var --safe --switch="$switch" share \
84+ | tr -d '\r')"
85+ switch_build_id="$switch_share_dir/ocaml/build-id"
86+ if [ -e "$switch_build_id" ]; then
87+ if [ x"$build_id" = x"$(head -n 1 "$switch_build_id")" ]; then
88+ echo "🔁 Prefer to re-clone from $switch"
89+ echo "$switch" > opam-switches
90+ origin="$switch"
91+ if ln "$switch_build_id" __cp_test 2>/dev/null; then
92+ rm __cp_test
93+ clone_mechanism='hard-linking'
94+ fi
95+ fi
96+ fi
97+ fi
98+ fi
99+100+ echo "🐫 Requesting list of switches from opam"
101+ opam switch list --safe --short | tr -d '\r' | grep -Fxv "$OPAMSWITCH" \
102+ >> opam-switches 2> /dev/null || true
103+104+ while IFS= read -r switch; do
105+ switch_share_dir="$(opam var --safe --switch="$switch" share | tr -d '\r')"
106+ switch_build_id="$switch_share_dir/ocaml/build-id"
107+ if [ -e "$switch_build_id" ]; then
108+ if [ x"$build_id" = x"$(head -n 1 "$switch_build_id")" ]; then
109+ # There are three ways of cloning a switch:
110+ # - Copy-on-Write (cp --reflink=always)
111+ # - Hard linking
112+ # - Copy
113+ # Copy-on-Write is the ideal - virtually no space overhead, but with
114+ # defence against accidental subsequent alterations. Hard linking is
115+ # preferred over copying for the space-saving, and because the
116+ # compiler should not being subsequently altered.
117+ if cp --reflink=always "$switch_build_id" __cp_test 2>/dev/null; then
118+ rm __cp_test
119+ echo "📝 - can reflink from: $switch"
120+ origin="$switch"
121+ clone_mechanism='copy-on-write'
122+ break
123+ elif ln "$switch_build_id" __cp_test 2>/dev/null; then
124+ rm __cp_test
125+ if [ -z "$clone_mechanism" ]; then
126+ echo "🔗 - can hard link from: $switch"
127+ origin="$switch"
128+ clone_mechanism='hard-linking'
129+ fi
130+ elif [ -z "$origin" ]; then
131+ echo "📄 - can copy from: $switch"
132+ origin="$switch"
133+ fi
134+ elif [ -z "$origin" ]; then
135+ echo "⛔ - different compiler: $switch"
136+ fi
137+ fi
138+ done < opam-switches
139+fi
140+141+{ echo "$build_id"; echo "$origin" ; } > build-id
142+143+if [ -n "$origin" ]; then
144+145+ echo "🧬 Will clone the compiler from $origin"
146+ test -n "$clone_mechanism" || clone_mechanism='copying'
147+148+ cloned='true'
149+ clone_source="$(sed -e '1d;s/\\/\\\\/g;s/%/%%/g;s/"/\\"/g' build-id)"
150+ case "$origin" in
151+ */*|*\\*) clone_source="local switch $clone_source";;
152+ *) clone_source="global switch $clone_source";;
153+ esac
154+155+ cat > "$package_name.install" <<'EOF'
156+share_root: [
157+ "build-id" {"ocaml/build-id"}
158+]
159+EOF
160+161+else
162+163+ echo "🏗️ Will build the compiler from sources"
164+165+ cloned='false'
166+ clone_source=''
167+168+ ./configure --cache-file=config.cache "$@"
169+ "$make" $make_args
170+ "$make" OPAM_PACKAGE_NAME=ocaml-compiler INSTALL_MODE=clone install
171+172+ cat > "$package_name.install" <<'EOF'
173+share_root: [
174+ "build-id" {"ocaml/build-id"}
175+ "ocaml-compiler-clone.sh" {"ocaml/clone"}
176+ "config.cache" {"ocaml/config.cache"}
177+ "config.status" {"ocaml/config.status"}
178+]
179+EOF
180+fi
181+182+# Create the .config file
183+cat > "$package_name.config" <<EOF
184+opam-version: "2.0"
185+variables {
186+ cloned: $cloned
187+ clone-source: "$clone_source"
188+ clone-mechanism: "$clone_mechanism"
189+}
190+EOF