My working unpac repository

Merge pull request #14246 from dra27/opam-install-file

Relocatable OCaml - to opam and beyond

authored by

Nick Barnes and committed by
GitHub
f6c8af41 674c2359

+1236 -396
+1
.gitattributes
··· 109 109 # Some Unicode characters here and there 110 110 utils/misc.ml typo.non-ascii 111 111 runtime/sak.c typo.non-ascii 112 + tools/opam/process.sh typo.non-ascii 112 113 113 114 testsuite/tests/** typo.missing-header typo.long-line=may 114 115 testsuite/tests/lib-bigarray-2/bigarrf.f typo.tab linguist-language=Fortran
+35 -8
.github/workflows/build-msvc.yml
··· 33 33 with: 34 34 script: | 35 35 // # Always test cl and clang-cl 36 - let compilers = ['cl', 'clang-cl']; 36 + let compilers = ['clang-cl']; 37 37 // # Also test i686 MSVC 38 38 let include = [ 39 - {cc: 'cl', arch: 'i686', libdir: 'relative'}]; 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:\\\\Бактріан🐫'}]; 40 42 let libdir = ['absolute']; 41 43 // # If this is a pull request, see if the PR has the 42 44 // # 'CI: Full matrix' label. This is done using an API request, ··· 53 55 // # Test Cygwin as well 54 56 compilers.push('gcc'); 55 57 // # Test bytecode-only Cygwin 56 - include.push({cc: 'gcc', arch: 'x86_64', libdir: 'absolute', config_arg: '--disable-native-toplevel --disable-native-compiler'}); 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'}); 57 59 // # Test i686 MSVC absolute 58 - include.push({cc: 'cl', arch: 'i686', libdir: 'absolute'}); 60 + include.push({os: 'windows-latest', prefix: '$PROGRAMFILES/Бактріан🐫', opam: ['false'], cc: 'cl', arch: 'i686', libdir: 'absolute'}); 59 61 // # Expand the main matrix to include relative testing 60 62 libdir.push('relative'); 61 63 } 62 64 } 63 - return {config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include}; 65 + return {os: ['windows-latest'], prefix: ['$PROGRAMFILES/Бактріан🐫'], opam: ['false'], config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include}; 64 66 - name: Determine if the testsuite should be skipped 65 67 id: skip 66 68 uses: actions/github-script@v7 ··· 78 80 build: 79 81 permissions: {} 80 82 81 - runs-on: windows-latest 83 + runs-on: ${{ matrix.os }} 82 84 83 85 needs: config 84 86 ··· 107 109 - name: Install Cygwin 108 110 uses: cygwin/cygwin-install-action@v3 109 111 with: 110 - packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-g++,gcc-fortran,' }}gcc-core 112 + packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-g++,gcc-fortran,' }}gcc-core,rsync,unzip 111 113 install-dir: 'D:\cygwin' 112 114 113 115 - name: Save Cygwin cache ··· 123 125 arch: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }} 124 126 if: matrix.cc != 'gcc' 125 127 128 + - 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 + 126 135 - name: Compute a key to cache configure results 127 136 id: autoconf-cache-key 128 137 env: ··· 141 150 env: 142 151 CONFIG_ARGS: >- 143 152 --cache-file=config.cache 144 - --prefix "${{ matrix.cc != 'gcc' && '$PROGRAMFILES\\Бактріан🐫' || '$(cygpath "$PROGRAMFILES/Бактріан🐫")'}}" 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) }} 145 155 ${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }} 146 156 ${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }} 147 157 --enable-ocamltest ··· 200 210 make tests 201 211 202 212 - name: Install the compiler 213 + if: matrix.opam != 'true' 203 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 204 231 205 232 - name: Test in prefix 206 233 run: |
+11 -4
.github/workflows/build.yml
··· 78 78 # debug runtime and minor heap verification. 79 79 # debug-s4096: select testsuite run with the debug runtime and a small 80 80 # minor heap. 81 + # opam: constructs an opam local switch from the compiler. 81 82 normal: 82 83 name: ${{ matrix.name }} 83 84 needs: [build, config] ··· 88 89 - id: normal 89 90 name: normal 90 91 dependencies: texlive-latex-extra texlive-fonts-recommended texlive-luatex hevea sass gdb lldb 92 + - id: opam 93 + name: opam installation 91 94 - id: debug 92 95 name: extra (debug) 93 96 - id: debug-s4096 ··· 134 137 - name: Install 135 138 if: matrix.id == 'normal' 136 139 run: | 137 - MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh install 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 138 145 - name: Test in prefix 139 - if: matrix.id == 'normal' 146 + if: matrix.id == 'normal' || matrix.id == 'opam' 140 147 run: | 141 - MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test-in-prefix 148 + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test-in-prefix 142 149 - name: Test in prefix (alternate configuration) 143 150 if: matrix.id == 'normal' && needs.config.outputs.full-matrix == 'true' 144 151 run: | 145 - MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh re-test-in-prefix 152 + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh re-test-in-prefix 146 153 - name: Build the manual 147 154 if: matrix.id == 'normal' && needs.build.outputs.manual_changed == 'true' 148 155 run: |
+1
.gitignore
··· 26 26 *.cmx[as] 27 27 *.cmti 28 28 *.annot 29 + *.stripped 29 30 *.exe 30 31 *.exe.manifest 31 32 .DS_Store
+246 -277
Makefile
··· 16 16 # The main Makefile 17 17 18 18 ROOTDIR = . 19 + SUBDIR_NAME = 20 + 19 21 # NOTE: it is important that the OCAMLDEP and OCAMLLEX variables 20 22 # are defined *before* Makefile.common gets included, so that 21 23 # their local definitions here take precedence over their ··· 51 53 PERVASIVES=$(STDLIB_MODULES) outcometree topprinters topdirs toploop 52 54 53 55 LIBFILES=stdlib.cma std_exit.cmo *.cmi $(HEADER_NAME) 54 - 55 - COMPLIBDIR=$(LIBDIR)/compiler-libs 56 56 57 57 TOPINCLUDES=$(addprefix -I otherlibs/,$(filter-out %threads,$(OTHERLIBRARIES))) 58 58 ··· 935 935 rm -f flexlink.opt flexlink.opt.exe \ 936 936 $(OPT_BINDIR)/flexlink $(OPT_BINDIR)/flexlink.exe 937 937 938 - INSTALL_COMPLIBDIR = $(DESTDIR)$(COMPLIBDIR) 939 - INSTALL_FLEXDLLDIR = $(INSTALL_LIBDIR)/flexdll 940 938 FLEXDLL_MANIFEST = default$(filter-out _i386,_$(ARCH)).manifest 941 939 942 940 DOC_FILES=\ ··· 988 986 endif 989 987 990 988 partialclean:: 991 - rm -f ocamlc ocamlc.exe ocamlc.opt ocamlc.opt.exe 989 + rm -f ocamlc ocamlc.exe ocamlc.opt ocamlc.opt.exe ocamlc*.stripped 992 990 993 991 # The native-code compiler 994 992 ··· 999 997 ocamlopt_BYTECODE_LINKFLAGS = -g 1000 998 1001 999 partialclean:: 1002 - rm -f ocamlopt ocamlopt.exe ocamlopt.opt ocamlopt.opt.exe 1000 + rm -f ocamlopt ocamlopt.exe ocamlopt.opt ocamlopt.opt.exe ocamlopt*.stripped 1003 1001 1004 1002 # The toplevel 1005 1003 ··· 2749 2747 $(BYTE_BUILD_TREE) $(OPT_BUILD_TREE) 2750 2748 rm -f config.log config.status libtool 2751 2749 2752 - INSTALL_LIBDIR_DYNLINK = $(INSTALL_LIBDIR)/dynlink 2750 + # 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 2753 2764 2754 2765 # 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. 2755 2777 2756 - .PHONY: install 2757 - install:: 2758 - $(MKDIR) "$(INSTALL_BINDIR)" 2759 - $(MKDIR) "$(INSTALL_LIBDIR)" 2760 - ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true" 2761 - $(MKDIR) "$(INSTALL_STUBLIBDIR)" 2778 + ifeq "$(NATIVE_COMPILER)" "true" 2779 + install: full-installoptopt 2780 + $(call INSTALL_END) 2781 + else 2782 + install: common-install 2783 + $(call INSTALL_END) 2762 2784 endif 2763 - $(MKDIR) "$(INSTALL_COMPLIBDIR)" 2764 - $(MKDIR) "$(INSTALL_DOCDIR)" 2765 - $(MKDIR) "$(INSTALL_INCDIR)" 2766 - $(MKDIR) "$(INSTALL_LIBDIR_PROFILING)" 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) 2767 2813 2768 2814 ifeq "$(SUFFIXING)" "true" 2769 2815 MANGLE_RUNTIME_NAME = $(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE) ··· 2774 2820 endif 2775 2821 2776 2822 define INSTALL_RUNTIME 2777 - install:: 2778 - $(INSTALL_PROG) \ 2779 - runtime/$(1)$(EXE) \ 2780 - "$(INSTALL_BINDIR)/$(call MANGLE_RUNTIME_NAME,$(1))" 2781 - ifeq "$(SUFFIXING)" "true" 2782 - cd "$(INSTALL_BINDIR)" && \ 2783 - $(LN) "$(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)" "$(1)$(EXE)" 2784 - cd "$(INSTALL_BINDIR)" && \ 2785 - $(LN) "$(TARGET)-$(1)-$(BYTECODE_RUNTIME_ID)$(EXE)" \ 2786 - "$(1)-$(ZINC_RUNTIME_ID)$(EXE)" 2787 - endif 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))) 2788 2827 endef 2789 2828 define INSTALL_RUNTIME_LIB 2790 2829 ifeq "$(2)" "BYTECODE" 2791 - install:: 2830 + common-install:: 2792 2831 else 2793 - installopt:: 2794 - endif 2795 - $(INSTALL_PROG) \ 2796 - runtime/lib$(1)_shared$(EXT_DLL) \ 2797 - "$(INSTALL_LIBDIR)/$(call MANGLE_RUNTIME_DLL_NAME,$(1),$(2))" 2798 - ifeq "$(SUFFIXING)" "true" 2799 - cd "$(INSTALL_LIBDIR)" && \ 2800 - $(LN) "$(call MANGLE_RUNTIME_DLL_NAME,$(1),$(2))" \ 2801 - "lib$(1)_shared$(EXT_DLL)" 2832 + full-installopt native-install:: 2802 2833 endif 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))) 2803 2837 endef 2804 2838 2805 2839 $(foreach runtime, $(runtime_PROGRAMS), \ 2806 2840 $(eval $(call INSTALL_RUNTIME,$(runtime)))) 2807 2841 2808 - install:: 2809 - $(INSTALL_DATA) runtime/ld.conf $(runtime_BYTECODE_STATIC_LIBRARIES) \ 2810 - "$(INSTALL_LIBDIR)" 2842 + common-install:: 2843 + $(call INSTALL_ITEMS, runtime/ld.conf $(runtime_BYTECODE_STATIC_LIBRARIES), \ 2844 + lib) 2811 2845 2812 2846 $(foreach shared_runtime, $(runtime_BYTECODE_SHARED_LIBRARIES), \ 2813 2847 $(eval $(call INSTALL_RUNTIME_LIB,$(shared_runtime),BYTECODE))) 2814 2848 2815 - install:: 2816 - $(INSTALL_DATA) runtime/caml/domain_state.tbl runtime/caml/*.h \ 2817 - "$(INSTALL_INCDIR)" 2818 - $(INSTALL_PROG) ocaml$(EXE) "$(INSTALL_BINDIR)" 2849 + 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) 2819 2854 ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2820 - $(call INSTALL_STRIPPED_BYTE_PROG,\ 2821 - ocamlc$(EXE),"$(INSTALL_BINDIR)/ocamlc.byte$(EXE)") 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 2822 2863 endif 2823 2864 $(MAKE) -C stdlib install 2865 + 2866 + define INSTALL_ONE_NAT_TOOL 2867 + common-install:: 2868 + ifeq "$(NATIVE_COMPILER)" "true" 2824 2869 ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2825 - $(INSTALL_PROG) lex/ocamllex$(EXE) \ 2826 - "$(INSTALL_BINDIR)/ocamllex.byte$(EXE)" 2827 - for i in $(TOOLS_TO_INSTALL_NAT); \ 2828 - do \ 2829 - $(INSTALL_PROG) "tools/$$i$(EXE)" "$(INSTALL_BINDIR)/$$i.byte$(EXE)";\ 2830 - if test -f "tools/$$i".opt$(EXE); then \ 2831 - $(INSTALL_PROG) "tools/$$i.opt$(EXE)" "$(INSTALL_BINDIR)" && \ 2832 - (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ 2833 - else \ 2834 - (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.byte$(EXE)" "$$i$(EXE)"); \ 2835 - fi; \ 2836 - done 2870 + $$(call INSTALL_ITEM, tools/$(1)$(EXE), bin, , $(1).byte$(EXE)) 2871 + endif 2872 + $$(call INSTALL_ITEM, tools/$(1).opt$(EXE), bin, , , $(1)$(EXE)) 2837 2873 else 2838 - for i in $(TOOLS_TO_INSTALL_NAT); \ 2839 - do \ 2840 - if test -f "tools/$$i".opt$(EXE); then \ 2841 - $(INSTALL_PROG) "tools/$$i.opt$(EXE)" "$(INSTALL_BINDIR)"; \ 2842 - (cd "$(INSTALL_BINDIR)" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \ 2843 - fi; \ 2844 - done 2874 + $$(call INSTALL_ITEM, tools/$(1)$(EXE), bin, , $(1).byte$(EXE), $(1)$(EXE)) 2845 2875 endif 2846 - for i in $(TOOLS_TO_INSTALL_BYT); \ 2847 - do \ 2848 - $(INSTALL_PROG) "tools/$$i$(EXE)" "$(INSTALL_BINDIR)";\ 2849 - done 2850 - $(INSTALL_PROG) $(ocamlyacc_PROGRAM)$(EXE) "$(INSTALL_BINDIR)" 2851 - $(INSTALL_DATA) \ 2852 - utils/*.cmi \ 2853 - parsing/*.cmi \ 2854 - typing/*.cmi \ 2855 - bytecomp/*.cmi \ 2856 - file_formats/*.cmi \ 2857 - lambda/*.cmi \ 2858 - driver/*.cmi \ 2859 - toplevel/*.cmi \ 2860 - "$(INSTALL_COMPLIBDIR)" 2861 - $(INSTALL_DATA) \ 2862 - toplevel/byte/*.cmi \ 2863 - "$(INSTALL_COMPLIBDIR)" 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)) 2864 2905 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 2865 - $(INSTALL_DATA) \ 2866 - utils/*.cmt utils/*.cmti utils/*.mli \ 2867 - parsing/*.cmt parsing/*.cmti parsing/*.mli \ 2868 - typing/*.cmt typing/*.cmti typing/*.mli \ 2869 - file_formats/*.cmt file_formats/*.cmti file_formats/*.mli \ 2870 - lambda/*.cmt lambda/*.cmti lambda/*.mli \ 2871 - bytecomp/*.cmt bytecomp/*.cmti bytecomp/*.mli \ 2872 - driver/*.cmt driver/*.cmti driver/*.mli \ 2873 - toplevel/*.cmt toplevel/*.cmti toplevel/*.mli \ 2874 - "$(INSTALL_COMPLIBDIR)" 2875 - $(INSTALL_DATA) \ 2876 - toplevel/byte/*.cmt \ 2877 - "$(INSTALL_COMPLIBDIR)" 2878 - $(INSTALL_DATA) \ 2879 - tools/profiling.cmt tools/profiling.cmti \ 2880 - "$(INSTALL_LIBDIR_PROFILING)" 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)) 2881 2913 endif 2882 - $(INSTALL_DATA) \ 2883 - compilerlibs/*.cma compilerlibs/META \ 2884 - "$(INSTALL_COMPLIBDIR)" 2885 - $(INSTALL_DATA) \ 2886 - $(ocamlc_CMO_FILES) $(ocaml_CMO_FILES) \ 2887 - "$(INSTALL_COMPLIBDIR)" 2888 - $(INSTALL_PROG) $(expunge) "$(INSTALL_LIBDIR)" 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) 2889 2919 # If installing over a previous OCaml version, ensure some modules are removed 2890 2920 # from the previous installation. 2891 - rm -f "$(INSTALL_LIBDIR)"/topdirs.cm* "$(INSTALL_LIBDIR)/topdirs.mli" 2892 - rm -f "$(INSTALL_LIBDIR)"/profiling.cm* "$(INSTALL_LIBDIR)/profiling.$(O)" 2893 - $(INSTALL_DATA) \ 2894 - tools/profiling.cmi tools/profiling.cmo \ 2895 - "$(INSTALL_LIBDIR_PROFILING)" 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)) 2896 2927 ifeq "$(UNIX_OR_WIN32)" "unix" # Install manual pages only on Unix 2897 2928 $(MAKE) -C man install 2898 2929 endif 2899 2930 # For dynlink, if installing over a previous OCaml version, ensure 2900 2931 # dynlink is removed from the previous installation. 2901 - rm -f "$(INSTALL_LIBDIR)"/dynlink.cm* "$(INSTALL_LIBDIR)/dynlink.mli" \ 2902 - "$(INSTALL_LIBDIR)/dynlink.$(A)" \ 2903 - $(addprefix "$(INSTALL_LIBDIR)/", $(notdir $(dynlink_CMX_FILES))) 2904 - $(MKDIR) "$(INSTALL_LIBDIR_DYNLINK)" 2905 - $(INSTALL_DATA) \ 2906 - otherlibs/dynlink/dynlink.cmi otherlibs/dynlink/dynlink.cma \ 2907 - otherlibs/dynlink/META \ 2908 - "$(INSTALL_LIBDIR_DYNLINK)" 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)) 2909 2941 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 2910 - $(INSTALL_DATA) \ 2911 - otherlibs/dynlink/dynlink.cmti otherlibs/dynlink/dynlink.mli \ 2912 - "$(INSTALL_LIBDIR_DYNLINK)" 2942 + $(call INSTALL_ITEMS, \ 2943 + otherlibs/dynlink/dynlink.cmti otherlibs/dynlink/dynlink.mli, \ 2944 + lib, $(INSTALL_LIBDIR_DYNLINK)) 2913 2945 endif 2914 2946 for i in $(OTHERLIBS); do \ 2915 2947 $(MAKE) -C otherlibs/$$i install || exit $$?; \ 2916 2948 done 2917 2949 ifeq "$(build_ocamldoc)" "true" 2918 - $(MKDIR) "$(INSTALL_LIBDIR)/ocamldoc" 2919 - $(INSTALL_PROG) $(OCAMLDOC) "$(INSTALL_BINDIR)" 2920 - $(INSTALL_DATA) \ 2921 - ocamldoc/ocamldoc.hva ocamldoc/*.cmi ocamldoc/odoc_info.cma \ 2922 - ocamldoc/META \ 2923 - "$(INSTALL_LIBDIR)/ocamldoc" 2924 - $(INSTALL_DATA) \ 2925 - $(OCAMLDOC_LIBCMIS) \ 2926 - "$(INSTALL_LIBDIR)/ocamldoc" 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)) 2927 2955 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 2928 - $(INSTALL_DATA) \ 2929 - $(OCAMLDOC_LIBMLIS) $(OCAMLDOC_LIBCMTS) \ 2930 - "$(INSTALL_LIBDIR)/ocamldoc" 2956 + $(call INSTALL_ITEMS, $(OCAMLDOC_LIBMLIS) $(OCAMLDOC_LIBCMTS), \ 2957 + lib, $(INSTALL_LIBDIR_OCAMLDOC)) 2931 2958 endif 2932 2959 endif 2933 2960 ifeq "$(build_libraries_manpages)" "true" 2934 2961 $(MAKE) -C api_docgen install 2935 2962 endif 2936 - if test -n "$(WITH_DEBUGGER)"; then \ 2937 - $(INSTALL_PROG) debugger/ocamldebug$(EXE) "$(INSTALL_BINDIR)"; \ 2938 - fi 2963 + ifneq "$(WITH_DEBUGGER)" "" 2964 + $(call INSTALL_ITEMS, debugger/ocamldebug$(EXE), bin) 2965 + endif 2939 2966 ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true" 2940 2967 ifeq "$(TOOLCHAIN)" "msvc" 2941 - $(INSTALL_DATA) $(FLEXDLL_SOURCE_DIR)/$(FLEXDLL_MANIFEST) \ 2942 - "$(INSTALL_BINDIR)/" 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) 2943 2971 endif 2944 2972 ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2945 - $(INSTALL_PROG) \ 2946 - flexlink.byte$(EXE) "$(INSTALL_BINDIR)" 2947 - endif # ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2948 - $(MKDIR) "$(INSTALL_FLEXDLLDIR)" 2949 - $(INSTALL_DATA) $(FLEXDLL_OBJECTS) "$(INSTALL_FLEXDLLDIR)" 2950 - endif # ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true" 2951 - $(INSTALL_DATA) Makefile.config "$(INSTALL_LIBDIR)" 2952 - $(INSTALL_DATA) $(DOC_FILES) "$(INSTALL_DOCDIR)" 2953 - ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2954 - if test -f ocamlopt$(EXE); then $(MAKE) installopt; else \ 2955 - cd "$(INSTALL_BINDIR)"; \ 2956 - $(LN) ocamlc.byte$(EXE) ocamlc$(EXE); \ 2957 - $(LN) ocamllex.byte$(EXE) ocamllex$(EXE); \ 2958 - (test -f flexlink.byte$(EXE) && \ 2959 - $(LN) flexlink.byte$(EXE) flexlink$(EXE)) || true; \ 2960 - fi 2973 + ifeq "$(NATIVE_COMPILER)" "true" 2974 + $(call INSTALL_ITEMS, flexlink.byte$(EXE), bin) 2961 2975 else 2962 - if test -f ocamlopt$(EXE); then $(MAKE) installopt; fi 2976 + $(call INSTALL_ITEM, flexlink.byte$(EXE), bin, , , flexlink$(EXE)) 2963 2977 endif 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) 2964 2983 2965 2984 # Installation of the native-code compiler 2966 - .PHONY: installopt 2967 - installopt:: 2968 - $(INSTALL_DATA) $(runtime_NATIVE_STATIC_LIBRARIES) "$(INSTALL_LIBDIR)" 2985 + .PHONY: full-installopt native-install 2986 + full-installopt native-install:: 2987 + $(call INSTALL_ITEMS, $(runtime_NATIVE_STATIC_LIBRARIES), lib) 2969 2988 2970 2989 $(foreach shared_runtime, $(runtime_NATIVE_SHARED_LIBRARIES), \ 2971 2990 $(eval $(call INSTALL_RUNTIME_LIB,$(shared_runtime),NATIVE))) 2972 2991 2973 - installopt:: 2992 + full-installopt native-install:: 2974 2993 ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 2975 - $(call INSTALL_STRIPPED_BYTE_PROG,\ 2976 - ocamlopt$(EXE),"$(INSTALL_BINDIR)/ocamlopt.byte$(EXE)") 2994 + $(call STRIP_BYTE_PROG, ocamlopt$(EXE)) 2995 + $(call INSTALL_ITEM, ocamlopt$(EXE).stripped, bin, , ocamlopt.byte$(EXE)) 2977 2996 endif 2978 2997 $(MAKE) -C stdlib installopt 2979 - $(INSTALL_DATA) \ 2980 - middle_end/*.cmi \ 2981 - "$(INSTALL_COMPLIBDIR)" 2982 - $(INSTALL_DATA) \ 2983 - middle_end/closure/*.cmi \ 2984 - "$(INSTALL_COMPLIBDIR)" 2985 - $(INSTALL_DATA) \ 2986 - middle_end/flambda/*.cmi \ 2987 - "$(INSTALL_COMPLIBDIR)" 2988 - $(INSTALL_DATA) \ 2989 - middle_end/flambda/base_types/*.cmi \ 2990 - "$(INSTALL_COMPLIBDIR)" 2991 - $(INSTALL_DATA) \ 2992 - asmcomp/*.cmi \ 2993 - "$(INSTALL_COMPLIBDIR)" 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)) 2994 3013 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 2995 - $(INSTALL_DATA) \ 2996 - middle_end/*.cmt middle_end/*.cmti \ 2997 - middle_end/*.mli \ 2998 - "$(INSTALL_COMPLIBDIR)" 2999 - $(INSTALL_DATA) \ 3000 - middle_end/closure/*.cmt middle_end/closure/*.cmti \ 3001 - middle_end/closure/*.mli \ 3002 - "$(INSTALL_COMPLIBDIR)" 3003 - $(INSTALL_DATA) \ 3004 - middle_end/flambda/*.cmt middle_end/flambda/*.cmti \ 3005 - middle_end/flambda/*.mli \ 3006 - "$(INSTALL_COMPLIBDIR)" 3007 - $(INSTALL_DATA) \ 3008 - middle_end/flambda/base_types/*.cmt \ 3009 - middle_end/flambda/base_types/*.cmti \ 3010 - middle_end/flambda/base_types/*.mli \ 3011 - "$(INSTALL_COMPLIBDIR)" 3012 - $(INSTALL_DATA) \ 3013 - asmcomp/*.cmt asmcomp/*.cmti \ 3014 - asmcomp/*.mli \ 3015 - "$(INSTALL_COMPLIBDIR)" 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)) 3016 3029 endif 3017 - $(INSTALL_DATA) \ 3018 - $(ocamlopt_CMO_FILES) \ 3019 - "$(INSTALL_COMPLIBDIR)" 3030 + $(call INSTALL_ITEMS, $(ocamlopt_CMO_FILES), \ 3031 + lib, $(INSTALL_LIBDIR_COMPILERLIBS)) 3020 3032 ifeq "$(build_ocamldoc)" "true" 3021 - $(MKDIR) "$(INSTALL_LIBDIR)/ocamldoc" 3022 - $(INSTALL_PROG) $(OCAMLDOC_OPT) "$(INSTALL_BINDIR)" 3023 - $(INSTALL_DATA) \ 3024 - $(OCAMLDOC_LIBCMIS) \ 3025 - "$(INSTALL_LIBDIR)/ocamldoc" 3026 - ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 3027 - $(INSTALL_DATA) \ 3028 - $(OCAMLDOC_LIBMLIS) $(OCAMLDOC_LIBCMTS) \ 3029 - "$(INSTALL_LIBDIR)/ocamldoc" 3030 - endif 3031 - $(INSTALL_DATA) \ 3032 - ocamldoc/ocamldoc.hva ocamldoc/*.cmx ocamldoc/odoc_info.$(A) \ 3033 - ocamldoc/odoc_info.cmxa \ 3034 - "$(INSTALL_LIBDIR)/ocamldoc" 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)) 3035 3037 endif 3036 3038 ifeq "$(strip $(NATDYNLINK))" "true" 3037 - $(INSTALL_DATA) \ 3038 - $(dynlink_CMX_FILES) otherlibs/dynlink/dynlink.cmxa \ 3039 - otherlibs/dynlink/dynlink.$(A) \ 3040 - "$(INSTALL_LIBDIR_DYNLINK)" 3039 + $(call INSTALL_ITEMS, \ 3040 + $(dynlink_CMX_FILES) otherlibs/dynlink/dynlink.cmxa \ 3041 + otherlibs/dynlink/dynlink.$(A), \ 3042 + lib, $(INSTALL_LIBDIR_DYNLINK)) 3041 3043 endif 3042 3044 for i in $(OTHERLIBS); do \ 3043 3045 $(MAKE) -C otherlibs/$$i installopt || exit $$?; \ 3044 3046 done 3045 - ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true" 3046 - if test -f ocamlopt.opt$(EXE); then $(MAKE) installoptopt; else \ 3047 - cd "$(INSTALL_BINDIR)"; \ 3048 - $(LN) ocamlc.byte$(EXE) ocamlc$(EXE); \ 3049 - $(LN) ocamlopt.byte$(EXE) ocamlopt$(EXE); \ 3050 - $(LN) ocamllex.byte$(EXE) ocamllex$(EXE); \ 3051 - (test -f flexlink.byte$(EXE) && \ 3052 - $(LN) flexlink.byte$(EXE) flexlink$(EXE)) || true; \ 3053 - fi 3054 - else 3055 - if test -f ocamlopt.opt$(EXE); then $(MAKE) installoptopt; fi 3056 - endif 3057 - $(INSTALL_DATA) \ 3058 - tools/profiling.cmx tools/profiling.$(O) \ 3059 - "$(INSTALL_LIBDIR_PROFILING)" 3047 + $(call INSTALL_ITEMS, tools/profiling.cmx tools/profiling.$(O), \ 3048 + lib, $(INSTALL_LIBDIR_PROFILING)) 3060 3049 3061 - .PHONY: installoptopt 3062 - installoptopt: 3063 - $(INSTALL_PROG) ocamlc.opt$(EXE) "$(INSTALL_BINDIR)" 3064 - $(INSTALL_PROG) ocamlopt.opt$(EXE) "$(INSTALL_BINDIR)" 3065 - $(INSTALL_PROG) lex/ocamllex.opt$(EXE) "$(INSTALL_BINDIR)" 3066 - cd "$(INSTALL_BINDIR)"; \ 3067 - $(LN) ocamlc.opt$(EXE) ocamlc$(EXE); \ 3068 - $(LN) ocamlopt.opt$(EXE) ocamlopt$(EXE); \ 3069 - $(LN) ocamllex.opt$(EXE) ocamllex$(EXE) 3050 + .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)) 3070 3055 ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true" 3071 - $(INSTALL_PROG) flexlink.opt$(EXE) "$(INSTALL_BINDIR)" 3072 - cd "$(INSTALL_BINDIR)"; \ 3073 - $(LN) flexlink.opt$(EXE) flexlink$(EXE) 3056 + $(call INSTALL_ITEM, flexlink.opt$(EXE), bin, , , flexlink$(EXE)) 3074 3057 endif 3075 - $(INSTALL_DATA) \ 3076 - utils/*.cmx parsing/*.cmx typing/*.cmx bytecomp/*.cmx \ 3077 - toplevel/*.cmx toplevel/native/*.cmx \ 3078 - toplevel/native/tophooks.cmi \ 3079 - file_formats/*.cmx \ 3080 - lambda/*.cmx \ 3081 - driver/*.cmx asmcomp/*.cmx middle_end/*.cmx \ 3082 - middle_end/closure/*.cmx \ 3083 - middle_end/flambda/*.cmx \ 3084 - middle_end/flambda/base_types/*.cmx \ 3085 - "$(INSTALL_COMPLIBDIR)" 3086 - $(INSTALL_DATA) \ 3087 - compilerlibs/*.cmxa compilerlibs/*.$(A) \ 3088 - "$(INSTALL_COMPLIBDIR)" 3089 - $(INSTALL_DATA) \ 3090 - $(ocamlc_CMX_FILES) $(ocamlc_CMX_FILES:.cmx=.$(O)) \ 3091 - $(ocamlopt_CMX_FILES) $(ocamlopt_CMX_FILES:.cmx=.$(O)) \ 3092 - $(ocamlnat_CMX_FILES:.cmx=.$(O)) \ 3093 - "$(INSTALL_COMPLIBDIR)" 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)) 3094 3069 ifeq "$(INSTALL_OCAMLNAT)" "true" 3095 - $(INSTALL_PROG) ocamlnat$(EXE) "$(INSTALL_BINDIR)" 3070 + $(call INSTALL_ITEMS, ocamlnat$(EXE), bin) 3096 3071 endif 3097 3072 3098 3073 # Installation of the *.ml sources of compiler-libs 3099 3074 .PHONY: install-compiler-sources 3100 3075 install-compiler-sources: 3101 3076 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 3102 - $(INSTALL_DATA) \ 3103 - utils/*.ml parsing/*.ml typing/*.ml bytecomp/*.ml driver/*.ml \ 3104 - file_formats/*.ml \ 3105 - lambda/*.ml \ 3106 - toplevel/*.ml toplevel/byte/*.ml \ 3107 - middle_end/*.ml middle_end/closure/*.ml \ 3108 - middle_end/flambda/*.ml middle_end/flambda/base_types/*.ml \ 3109 - asmcomp/*.ml \ 3110 - asmcmp/debug/*.ml \ 3111 - "$(INSTALL_COMPLIBDIR)" 3077 + $(call INSTALL_ITEMS, \ 3078 + $(call COMPILER_ARTEFACT_DIRS, *.ml, $(NATIVE_ARTEFACT_DIRS)) \ 3079 + toplevel/byte/*.ml, \ 3080 + lib, $(INSTALL_LIBDIR_COMPILERLIBS)) 3112 3081 endif 3113 3082 3114 3083 include .depend
+350 -15
Makefile.common
··· 86 86 endif 87 87 88 88 DESTDIR ?= 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) 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) 98 434 99 435 FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile) 100 436 ··· 510 846 $(eval $(call _OCAML_NATIVE_LIBRARY,$(1))) 511 847 endef # OCAML_LIBRARY 512 848 513 - # 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 849 + # 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 519 854 520 855 # ocamlc has several mechanisms for linking a bytecode image to the runtime 521 856 # which executes it. The exact mechanism depends on the platform and the precise
+1
api_docgen/Makefile
··· 14 14 #************************************************************************** 15 15 # Used by included Makefiles 16 16 ROOTDIR = .. 17 + SUBDIR_NAME = api_docgen 17 18 -include ../Makefile.build_config 18 19 19 20 odoc-%:
+2 -4
api_docgen/ocamldoc/Makefile
··· 14 14 #************************************************************************** 15 15 # Used by included Makefiles 16 16 ROOTDIR = ../.. 17 + SUBDIR_NAME = api_docgen/ocamldoc 17 18 include ../Makefile.common 18 19 vpath %.mli ../../stdlib $(DOC_COMPILERLIBS_DIRS) $(DOC_STDLIB_DIRS) 19 20 ··· 121 122 122 123 .PHONY: install 123 124 install: 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 125 + $(call INSTALL_ITEMS_OPT, build/man/*.3o, man, $(INSTALL_MANDIR_LIBRARIES))
+5 -7
api_docgen/odoc/Makefile
··· 15 15 16 16 # Used by included Makefiles 17 17 ROOTDIR = ../.. 18 + SUBDIR_NAME = api_docgen/odoc 18 19 19 20 include ../Makefile.common 20 21 ··· 191 192 # Man pages are the only installed documentation 192 193 .PHONY: install 193 194 install: 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 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)) 201 199 202 200 # Dependencies for stdlib modules. 203 201 # Use the same dependencies used for compiling .cmx files.
+2 -2
man/Makefile
··· 14 14 #************************************************************************** 15 15 16 16 ROOTDIR = .. 17 + SUBDIR_NAME = man 17 18 include $(ROOTDIR)/Makefile.common 18 19 19 20 MANPAGES = $(addsuffix .1,\ ··· 22 23 23 24 .PHONY: install 24 25 install: 25 - $(MKDIR) $(call QUOTE_SINGLE,$(INSTALL_PROGRAMS_MAN_DIR)) 26 - $(INSTALL_DATA) $(MANPAGES) $(call QUOTE_SINGLE,$(INSTALL_PROGRAMS_MAN_DIR)) 26 + $(call INSTALL_ITEMS, $(MANPAGES), man, $(INSTALL_MANDIR_PROGRAMS))
+10 -9
ocaml-variants.opam
··· 39 39 # facility is not yet available for other platforms. 40 40 "host-arch-x86_32" {os != "win32" & arch = "x86_32" & post} 41 41 ("host-arch-x86_64" {os != "win32" & arch = "x86_64" & post} | 42 - ("host-arch-x86_32" {os != "win32" & arch = "x86_64" & post} & "ocaml-option-32bit" {os != "win32" & arch = "x86_64"})) 42 + ("host-arch-x86_32" {os != "win32" & arch = "x86_64" & post} & "ocaml-option-32bit" {build & os != "win32" & arch = "x86_64"})) 43 43 "host-arch-unknown" {os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" & arch != "riscv64" & arch != "s390x" & arch != "x86_32" & arch != "x86_64" & post} 44 44 45 45 # Port selection (Windows) 46 46 # amd64 mingw-w64 / MSVC 47 - (("arch-x86_64" {os = "win32" & arch = "x86_64"} & 48 - (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | 49 - ("system-msvc" & "winpthreads" & "ocaml-option-no-compression" {os = "win32"}))) | 47 + (("arch-x86_64" {build & os = "win32" & arch = "x86_64"} & 48 + (("system-mingw" {build} & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | 49 + ("system-msvc" {build} & "winpthreads" {os = "win32"} & "ocaml-option-no-compression" {build & os = "win32"}))) | 50 50 # i686 mingw-w64 / MSVC 51 - ("arch-x86_32" {os = "win32"} & "ocaml-option-bytecode-only" {os = "win32"} & 52 - (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | 53 - ("system-msvc" & "winpthreads" & "ocaml-option-no-compression" {os = "win32"}))) | 51 + ("arch-x86_32" {build & os = "win32"} & "ocaml-option-bytecode-only" {build & os = "win32"} & 52 + (("system-mingw" {build} & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | 53 + ("system-msvc" {build} & "winpthreads" {os = "win32"} & "ocaml-option-no-compression" {build & os = "win32"}))) | 54 54 # Non-Windows systems 55 55 "host-system-other" {os != "win32" & post}) 56 56 ··· 81 81 "--enable-runtime-search" 82 82 "--enable-runtime-search-target=fallback" 83 83 "--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed} 84 - "--with-winpthreads-msvc=%{winpthreads:share}%" {system-msvc:installed} 84 + "--with-winpthreads-msvc=%{winpthreads:share}%" {winpthreads:installed & system-msvc:installed} 85 85 "-C" 86 86 "--with-afl" {ocaml-option-afl:installed} 87 87 "--disable-native-compiler" {ocaml-option-bytecode-only:installed} ··· 107 107 "--disable-warn-error" 108 108 ] 109 109 [make "-j%{jobs}%"] 110 + [make "INSTALL_MODE=opam" "install"] 110 111 ] 111 - install: [make "install"] 112 + install: ["sh" "./%{name}%-fixup.sh" prefix] 112 113 depopts: [ 113 114 "ocaml-option-32bit" 114 115 "ocaml-option-afl"
+1
otherlibs/Makefile
··· 14 14 #************************************************************************** 15 15 16 16 ROOTDIR=.. 17 + SUBDIR_NAME=otherlibs 17 18 include $(ROOTDIR)/Makefile.common 18 19 19 20 # Although the OTHERLIBS variable is defined in ../Makefile.config,
+23 -30
otherlibs/Makefile.otherlibs.common
··· 16 16 # Common Makefile for otherlibs 17 17 18 18 ROOTDIR=../.. 19 + SUBDIR_NAME=otherlibs/$(LIBNAME) 19 20 include $(ROOTDIR)/Makefile.common 20 21 include $(ROOTDIR)/Makefile.best_binaries 21 22 ··· 109 110 lib$(CLIBNAME_NATIVE).$(A): $(COBJS) 110 111 $(V_OCAMLMKLIB)$(MKLIB) -oc $(CLIBNAME_NATIVE) $(COBJS_NATIVE) $(LDOPTS) 111 112 112 - INSTALL_LIBDIR_LIBNAME = $(INSTALL_LIBDIR)/$(LIBNAME) 113 - 114 113 install:: 115 114 ifneq "$(STUBSLIB_BYTECODE)" "" 116 115 ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true" 117 - $(INSTALL_PROG) $(STUBSDLL) "$(INSTALL_STUBLIBDIR)" 116 + $(call INSTALL_ITEMS, $(STUBSDLL), stublibs) 118 117 endif 119 - $(INSTALL_DATA) $(STUBSLIB_BYTECODE) "$(INSTALL_LIBDIR)/" 118 + $(call INSTALL_ITEMS, $(STUBSLIB_BYTECODE), lib) 120 119 endif 121 120 # If installing over a previous OCaml version, ensure the library is removed 122 121 # 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)/" 122 + $(call INSTALL_RM, \ 123 + $(addprefix "$(INSTALL_LIBDIR)"/, \ 124 + $(LIBNAME).cma $(CMIFILES) \ 125 + $(CMIFILES:.cmi=.mli) $(CMIFILES:.cmi=.cmti) \ 126 + $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).cmxs $(LIBNAME).$(A))) 127 + $(call INSTALL_ITEMS, $(LIBNAME).cma $(CMIFILES) META, lib, $(LIBNAME)) 131 128 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 132 - $(INSTALL_DATA) \ 133 - $(CMIFILES:.cmi=.mli) \ 134 - $(CMIFILES:.cmi=.cmti) \ 135 - "$(INSTALL_LIBDIR_LIBNAME)/" 129 + $(call INSTALL_ITEMS, $(CMIFILES:.cmi=.mli) $(CMIFILES:.cmi=.cmti), \ 130 + lib, $(LIBNAME)) 136 131 endif 137 - if test -n "$(HEADERS)"; then \ 138 - $(INSTALL_DATA) $(HEADERS) "$(INSTALL_INCDIR)/"; \ 139 - fi 132 + ifneq "$(HEADERS)" "" 133 + $(call INSTALL_ITEMS, $(HEADERS), lib, $(INSTALL_LIBDIR_CAML)) 134 + endif 140 135 141 136 installopt: 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 137 + $(call INSTALL_ITEMS, \ 138 + $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).$(A), lib, $(LIBNAME)) 139 + ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true" 140 + $(call INSTALL_ITEMS, $(LIBNAME).cmxs, libexec, $(LIBNAME)) 141 + ifeq "$(SUFFIXING)" "false" 142 + $(call INSTALL_ITEMS, dll$(CLIBNAME_NATIVE)$(EXT_DLL), stublibs) 143 + endif 144 + endif 152 145 ifneq "$(STUBSLIB_NATIVE)" "" 153 - $(INSTALL_DATA) $(STUBSLIB_NATIVE) "$(INSTALL_LIBDIR)/" 146 + $(call INSTALL_ITEMS, $(STUBSLIB_NATIVE), lib) 154 147 endif 155 148 156 149 partialclean:
+10 -17
otherlibs/systhreads/Makefile
··· 14 14 #************************************************************************** 15 15 16 16 ROOTDIR=../.. 17 + SUBDIR_NAME=otherlibs/systhreads 17 18 18 19 include $(ROOTDIR)/Makefile.common 19 20 include $(ROOTDIR)/Makefile.best_binaries ··· 103 104 distclean: clean 104 105 rm -f META 105 106 106 - INSTALL_THREADSLIBDIR=$(INSTALL_LIBDIR)/$(LIBNAME) 107 - 108 107 install: 109 108 ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true" 110 - $(INSTALL_PROG) $(DLLTHREADS) "$(INSTALL_STUBLIBDIR)" 109 + $(call INSTALL_ITEMS, $(DLLTHREADS), stublibs) 111 110 endif 112 - $(INSTALL_DATA) libthreads.$(A) "$(INSTALL_LIBDIR)" 113 - $(MKDIR) "$(INSTALL_THREADSLIBDIR)" 114 - $(INSTALL_DATA) \ 115 - $(CMIFILES) threads.cma META \ 116 - "$(INSTALL_THREADSLIBDIR)" 111 + $(call INSTALL_ITEMS, libthreads.$(A), lib) 112 + $(call INSTALL_ITEMS, $(CMIFILES) threads.cma META, lib, $(LIBNAME)) 117 113 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 118 - $(INSTALL_DATA) \ 119 - $(CMIFILES:.cmi=.cmti) \ 120 - "$(INSTALL_THREADSLIBDIR)" 121 - $(INSTALL_DATA) $(MLIFILES) "$(INSTALL_THREADSLIBDIR)" 114 + $(call INSTALL_ITEMS, $(CMIFILES:.cmi=.cmti), lib, $(LIBNAME)) 115 + $(call INSTALL_ITEMS, $(MLIFILES), lib, $(LIBNAME)) 122 116 endif 123 - $(INSTALL_DATA) caml/threads.h "$(INSTALL_INCDIR)" 117 + $(call INSTALL_ITEMS, caml/threads.h, lib, $(INSTALL_LIBDIR_CAML)) 124 118 125 119 installopt: 126 - $(INSTALL_DATA) libthreadsnat.$(A) "$(INSTALL_LIBDIR)" 127 - $(INSTALL_DATA) \ 128 - $(THREADS_NCOBJS) threads.cmxa threads.$(A) \ 129 - "$(INSTALL_THREADSLIBDIR)" 120 + $(call INSTALL_ITEMS, libthreadsnat.$(A), lib) 121 + $(call INSTALL_ITEMS, $(THREADS_NCOBJS) threads.cmxa threads.$(A), \ 122 + lib, $(LIBNAME)) 130 123 131 124 %.cmi: %.mli 132 125 $(V_OCAMLC)$(CAMLC) -c $(COMPFLAGS) $<
+9 -13
stdlib/Makefile
··· 14 14 #************************************************************************** 15 15 16 16 ROOTDIR = .. 17 + SUBDIR_NAME = stdlib 17 18 # NOTE: it is important that the OCAMLDEP variable is defined *before* 18 19 # Makefile.common gets included, so that its local definition here 19 20 # take precedence over its general shared definitions in Makefile.common. ··· 47 48 OPTCOMPILER=$(ROOTDIR)/ocamlopt$(EXE) 48 49 CAMLOPT=$(OCAMLRUN) $(OPTCOMPILER) 49 50 51 + # At present, only META is installed to the package directory 52 + LIBNAME = stdlib 53 + 50 54 include StdlibModules 51 55 52 56 OBJS=$(addsuffix .cmo,$(STDLIB_MODULES)) ··· 60 64 allopt: stdlib.cmxa std_exit.cmx 61 65 opt.opt: allopt 62 66 63 - INSTALL_STDLIB_META_DIR=$(DESTDIR)$(LIBDIR)/stdlib 64 - 65 67 .PHONY: install 66 68 install:: 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)" 69 + $(call INSTALL_ITEMS, stdlib.cma std_exit.cmo *.cmi, lib) 70 + $(call INSTALL_ITEMS, META, lib, $(LIBNAME)) 71 71 ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true" 72 - $(INSTALL_DATA) \ 73 - *.cmt *.cmti *.mli *.ml *.ml.in \ 74 - "$(INSTALL_LIBDIR)" 72 + $(call INSTALL_ITEMS, *.cmt *.cmti *.mli *.ml *.ml.in, lib) 75 73 endif 76 - $(INSTALL_DATA) $(HEADER_NAME) "$(INSTALL_LIBDIR)/$(HEADER_NAME)" 74 + $(call INSTALL_ITEMS, $(HEADER_NAME), lib) 77 75 78 76 .PHONY: installopt 79 77 installopt: installopt-default 80 78 81 79 .PHONY: installopt-default 82 80 installopt-default: 83 - $(INSTALL_DATA) \ 84 - stdlib.cmxa stdlib.$(A) std_exit.$(O) *.cmx \ 85 - "$(INSTALL_LIBDIR)" 81 + $(call INSTALL_ITEMS, stdlib.cmxa stdlib.$(A) std_exit.$(O) *.cmx, lib) 86 82 87 83 MANGLING = $(filter true,$(SUFFIXING)) 88 84 runtime-launch-info: tmpheader.exe
+47 -5
tools/ci/actions/runner.sh
··· 16 16 17 17 set -xe 18 18 19 - PREFIX=~/local 19 + # The prefix is designed to be usable as an opam local switch 20 + PREFIX=~/local/_opam 20 21 21 22 MAKE="make $MAKE_ARG" 22 23 SHELL=dash ··· 56 57 # $CONFIG_ARG also appears last to allow settings specified here to be 57 58 # overridden by the workflows. 58 59 call-configure --prefix="$PREFIX" \ 60 + --docdir="$PREFIX/doc/ocaml" \ 59 61 --enable-flambda-invariants \ 60 62 --enable-ocamltest \ 61 63 --enable-native-toplevel \ 62 64 --disable-dependency-generation \ 63 - $CONFIG_ARG 65 + -C $CONFIG_ARG 64 66 } 65 67 66 68 Build () { ··· 125 127 } 126 128 127 129 Install () { 128 - $MAKE install 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 129 150 } 130 151 131 152 target_libdir_is_relative='^ *TARGET_LIBDIR_IS_RELATIVE *= *false' ··· 225 246 # we would need to redo (small parts of) world.opt afterwards to 226 247 # use the compiler again 227 248 $MAKE check_all_arches 228 - # Ensure that .gitignore is up-to-date - this will fail if any untreacked or 249 + # Ensure that .gitignore is up-to-date - this will fail if any untracked or 229 250 # altered files exist. 230 251 test -z "$(git status --porcelain)" 231 252 # check that the 'clean' target also works ··· 234 255 $MAKE -C manual distclean 235 256 # check that the `distclean` target definitely cleans the tree 236 257 $MAKE distclean 237 - # Check the working tree is clean 258 + # Check the working tree is clean - config.cache is intentionally not deleted 259 + # by any of the clean targets 260 + rm config.cache 238 261 test -z "$(git status --porcelain)" 239 262 # Check that there are no ignored files 240 263 test -z "$(git ls-files --others -i --exclude-standard)" ··· 298 321 ReportBuildStatus 0 299 322 } 300 323 324 + 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 + 301 342 case $1 in 302 343 configure) Configure;; 303 344 build) Build;; ··· 311 352 manual) BuildManual;; 312 353 other-checks) Checks;; 313 354 basic-compiler) BasicCompiler;; 355 + opam) CreateSwitch;; 314 356 *) echo "Unknown CI instruction: $1" 315 357 exit 1;; 316 358 esac
+18 -4
tools/ci/appveyor/appveyor_build.cmd
··· 22 22 23 23 chcp 65001 > nul 24 24 set BUILD_PREFIX=🐫реализация 25 - set OCAMLROOT=%PROGRAMFILES%\Бактріан🐫 25 + set OCAMLROOT=C:\Бактріан🐫 26 26 27 27 if "%1" neq "install" goto %1 28 28 setlocal enabledelayedexpansion ··· 69 69 ) 70 70 ) 71 71 if "%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 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 + ) 73 79 "%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%" 74 80 if %CYGWIN_UPGRADE_REQUIRED% equ 1 ( 75 81 echo Cygwin package upgrade required - please go and drink coffee ··· 87 93 if "%PORT%" equ "mingw32" set SDK=call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" 88 94 ) 89 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= 90 101 goto :EOF 91 102 92 103 :install ··· 103 114 cd "%APPVEYOR_BUILD_FOLDER%" 104 115 appveyor DownloadFile "https://github.com/ocaml/flexdll/archive/%FLEXDLL_VERSION%.tar.gz" -FileName "flexdll.tar.gz" || exit /b 1 105 116 appveyor 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" 106 120 rem flexdll.zip is processed here, rather than in appveyor_build.sh because the 107 121 rem unzip command comes from MSYS2 (via Git for Windows) and it has to be 108 122 rem invoked via cmd /c in a bash script which is weird(er). ··· 115 129 rem CYGWIN_COMMANDS is a corresponding command to run with --version to test 116 130 rem whether the package works. This is used to verify whether the installation 117 131 rem needs upgrading. 118 - set CYGWIN_PACKAGES=cygwin make diffutils 119 - set CYGWIN_COMMANDS=cygcheck make diff 132 + set CYGWIN_PACKAGES=cygwin make diffutils unzip 133 + set CYGWIN_COMMANDS=cygcheck make diff unzip 120 134 if "%PORT%" equ "mingw32" ( 121 135 rem mingw64-i686-runtime does not need explicitly installing, but it's useful 122 136 rem to have the version reported.
+39 -1
tools/ci/appveyor/appveyor_build.sh
··· 59 59 CACHE_FILE_PREFIX="$CACHE_DIRECTORY/config.cache-$1" 60 60 CACHE_FILE="$CACHE_FILE_PREFIX-$CACHE_KEY" 61 61 62 - args=('--cache-file' "$CACHE_FILE" '--prefix' "$2" '--enable-ocamltest') 62 + args=('--cache-file' "$CACHE_FILE" \ 63 + '--prefix' "$2/_opam" \ 64 + '--docdir' "$2/_opam/doc/ocaml" \ 65 + '--enable-ocamltest') 63 66 64 67 case "$1" in 65 68 cygwin*) ··· 96 99 if ((failed)) ; then cat config.log ; exit $failed ; fi 97 100 fi 98 101 102 + cp "$CACHE_FILE" config.cache 103 + 99 104 # FILE=$(pwd | cygpath -f - -m)/Makefile.config 100 105 # run "Content of $FILE" cat Makefile.config 101 106 } ··· 103 108 PARALLEL_URL='https://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel' 104 109 APPVEYOR_BUILD_FOLDER=$(echo "$APPVEYOR_BUILD_FOLDER" | cygpath -f -) 105 110 FLEXDLLROOT="$PROGRAMFILES/flexdll" 111 + export OPAMSWITCH="$OCAMLROOT" 106 112 107 113 if [[ $BOOTSTRAP_FLEXDLL = 'false' ]] ; then 108 114 case "$PORT" in ··· 177 183 make -C "$FULL_BUILD_PREFIX-$PORT/testsuite" SHOW_TIMINGS=1 all 178 184 fi 179 185 run "install $PORT" $MAKE -C "$FULL_BUILD_PREFIX-$PORT" install 186 + make -C "$FULL_BUILD_PREFIX-$PORT" INSTALL_MODE=clone install 187 + ( 188 + cd "$OCAMLROOT" 189 + mv _opam destdir 190 + #ret="$PWD" 191 + #script="$PWD/ocaml-compiler-clone.sh" 192 + #cd "$(find $PWD/install -name _opam -type d)" 193 + mkdir -p "destdir/share/ocaml" 194 + cp "$FULL_BUILD_PREFIX-$PORT/config."{cache,status} 'destdir/share/ocaml/' 195 + cp "$FULL_BUILD_PREFIX-$PORT/ocaml-compiler-clone.sh" \ 196 + 'destdir/share/ocaml/clone' 197 + cd destdir 198 + sh "$FULL_BUILD_PREFIX-$PORT/ocaml-compiler-clone.sh" "$OCAMLROOT/_opam" 199 + ) 200 + rm -rf "$OCAMLROOT" 201 + $MAKE -C "$FULL_BUILD_PREFIX-$PORT" OPAM_PACKAGE_NAME=ocaml-variants \ 202 + INSTALL_MODE=opam install 203 + ( 204 + cd "$FULL_BUILD_PREFIX-$PORT" 205 + export PATH="$FLEXDLLROOT:$PATH" 206 + opam init --cli=2.4 --bare --yes --disable-sandboxing --auto-setup \ 207 + --cygwin-local-install 208 + # These commands intentionally run using opam's "default" CLI 209 + opam switch create "$OPAMSWITCH" --empty 210 + opam pin add --no-action --kind=path ocaml-variants . 211 + opam pin add --no-action flexdll flexdll 212 + opam install --yes flexdll winpthreads 213 + opam install --yes --assume-built ocaml-variants 214 + git checkout -- ocaml-variants.install 215 + rm -f config.cache ocaml-variants-fixup.sh ocaml-compiler-clone.sh 216 + opam exec -- ocamlc -v 217 + ) 180 218 run "test $PORT in prefix" \ 181 219 $MAKE -f Makefile.test -C "$FULL_BUILD_PREFIX-$PORT/testsuite/in_prefix" \ 182 220 test-in-prefix
+235
tools/opam/generate.ml
··· 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
+190
tools/opam/process.sh
··· 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