The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #14244 from dra27/enable-relative

Relocatable OCaml - `--with-relative-libdir`

authored by

Gabriel Scherer and committed by
GitHub
cfbf2105 f8ea2c42

+1601 -275
+4
.depend
··· 5230 5230 lambda/debuginfo.cmi \ 5231 5231 middle_end/convert_primitives.cmi \ 5232 5232 utils/config.cmi \ 5233 + middle_end/compilenv.cmi \ 5233 5234 middle_end/compilation_unit.cmi \ 5234 5235 middle_end/flambda/base_types/closure_origin.cmi \ 5235 5236 middle_end/flambda/base_types/closure_id.cmi \ ··· 5259 5260 lambda/debuginfo.cmx \ 5260 5261 middle_end/convert_primitives.cmx \ 5261 5262 utils/config.cmx \ 5263 + middle_end/compilenv.cmx \ 5262 5264 middle_end/compilation_unit.cmx \ 5263 5265 middle_end/flambda/base_types/closure_origin.cmx \ 5264 5266 middle_end/flambda/base_types/closure_id.cmx \ ··· 10776 10778 testsuite/tools/test_in_prefix.cmi 10777 10779 testsuite/tools/test_in_prefix.cmi : 10778 10780 testsuite/tools/test_ld_conf.cmo : \ 10781 + otherlibs/unix/unix.cmi \ 10779 10782 testsuite/tools/harness.cmi \ 10780 10783 testsuite/tools/environment.cmi \ 10781 10784 utils/config.cmi \ 10782 10785 testsuite/tools/test_ld_conf.cmi 10783 10786 testsuite/tools/test_ld_conf.cmx : \ 10787 + otherlibs/unix/unix.cmx \ 10784 10788 testsuite/tools/harness.cmx \ 10785 10789 testsuite/tools/environment.cmx \ 10786 10790 utils/config.cmx \
+11 -5
.github/workflows/build-msvc.yml
··· 36 36 let compilers = ['cl', 'clang-cl']; 37 37 // # Also test i686 MSVC 38 38 let include = [ 39 - {cc: 'cl', arch: 'i686'}]; 39 + {cc: 'cl', arch: 'i686', libdir: 'relative'}]; 40 + let libdir = ['absolute']; 40 41 // # If this is a pull request, see if the PR has the 41 42 // # 'CI: Full matrix' label. This is done using an API request, 42 43 // # rather than from context.payload.pull_request.labels, since we ··· 52 53 // # Test Cygwin as well 53 54 compilers.push('gcc'); 54 55 // # Test bytecode-only Cygwin 55 - include.push({cc: 'gcc', arch: 'x86_64', config_arg: '--disable-native-toplevel --disable-native-compiler'}); 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'); 56 61 } 57 62 } 58 - return {config_arg: [''], arch: ['x86_64'], cc: compilers, include: include}; 63 + return {config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include}; 59 64 - name: Determine if the testsuite should be skipped 60 65 id: skip 61 66 uses: actions/github-script@v7 ··· 79 84 80 85 timeout-minutes: ${{ matrix.cc == 'gcc' && 90 || 60 }} 81 86 82 - name: ${{ matrix.cc == 'cl' && 'MSVC' || matrix.cc == 'gcc' && 'Cygwin' || 'clang-cl' }} ${{ matrix.arch }} ${{ matrix.config_arg != '' && format('({0})', matrix.config_arg) || '' }} 87 + name: ${{ matrix.cc == 'cl' && 'MSVC' || matrix.cc == 'gcc' && 'Cygwin' || 'clang-cl' }} ${{ matrix.arch }} ${{ matrix.libdir }} ${{ matrix.config_arg != '' && format('({0})', matrix.config_arg) || '' }} 83 88 84 89 strategy: 85 90 matrix: ${{ fromJSON(needs.config.outputs.matrix) }} ··· 136 141 env: 137 142 CONFIG_ARGS: >- 138 143 --cache-file=config.cache 139 - --prefix "${{ matrix.cc != 'gcc' && '$PROGRAMFILES/Бактріан🐫' || '$(cygpath "$PROGRAMFILES/Бактріан🐫")'}}" 144 + --prefix "${{ matrix.cc != 'gcc' && '$PROGRAMFILES\\Бактріан🐫' || '$(cygpath "$PROGRAMFILES/Бактріан🐫")'}}" 140 145 ${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }} 141 146 ${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }} 142 147 --enable-ocamltest 143 148 ${{ endsWith(matrix.arch, '64') && '--enable-native-toplevel' || '--disable-native-toplevel' }} 149 + ${{ matrix.libdir == 'relative' && '--with-relative-libdir' || '--without-relative-libdir' }} 144 150 ${{ matrix.config_arg }} 145 151 run: | 146 152 eval $(tools/msvs-promote-path)
+29 -2
.github/workflows/build.yml
··· 59 59 '${{ github.event.repository.full_name }}' 60 60 - name: Configure tree 61 61 run: | 62 - MAKE_ARG=-j CONFIG_ARG='--enable-flambda --enable-cmm-invariants --enable-codegen-invariants --enable-dependency-generation --enable-native-toplevel' OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh configure 62 + MAKE_ARG=-j CONFIG_ARG='--enable-flambda --enable-cmm-invariants --enable-codegen-invariants --enable-dependency-generation --enable-native-toplevel --with-relative-libdir' OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh configure 63 63 - name: Build 64 64 run: | 65 65 MAKE_ARG=-j bash -xe tools/ci/actions/runner.sh build ··· 139 139 if: matrix.id == 'normal' 140 140 run: | 141 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 142 146 - name: Build the manual 143 147 if: matrix.id == 'normal' && needs.build.outputs.manual_changed == 'true' 144 148 run: | ··· 152 156 config: 153 157 runs-on: ubuntu-latest 154 158 outputs: 159 + full-matrix: ${{ steps.full.outputs.result }} 155 160 jobs: ${{ steps.jobs.outputs.result }} 156 161 skip-testsuite: ${{ steps.skip.outputs.result }} 157 162 steps: 163 + - name: Record if the build matrix is expanded 164 + id: full 165 + uses: actions/github-script@v7 166 + with: 167 + script: | 168 + let full_matrix = false; 169 + if (context.payload.pull_request) { 170 + const { data: labels } = 171 + await github.rest.issues.listLabelsOnIssue({...context.repo, issue_number: context.payload.pull_request.number}); 172 + full_matrix = labels.some(label => label.name === 'CI: Full matrix'); 173 + } 174 + console.log('Full matrix: ' + full_matrix); 175 + return full_matrix; 158 176 - name: Compute matrix for the "others" job 159 177 id: jobs 160 178 uses: actions/github-script@v7 ··· 169 187 {name: 'macos-x86_64', os: 'macos-15-intel', 170 188 'test-in-prefix': true}, 171 189 {name: 'macos-arm64', os: 'macos-latest', 190 + config_arg: '--with-relative-libdir', 172 191 'test-in-prefix': true}]; 173 192 // # If this is a pull request, see if the PR has the 174 193 // # 'CI: Full matrix' label. This is done using an API request, ··· 258 277 if: ${{ matrix.test-in-prefix }} 259 278 run: | 260 279 MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test-in-prefix 280 + - name: Test in prefix (alternate configuration) 281 + if: ${{ matrix.test-in-prefix && needs.config.outputs.full-matrix == 'true' }} 282 + run: | 283 + MAKE_ARG=-j OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh re-test-in-prefix 261 284 262 285 i386: 263 286 runs-on: ubuntu-latest ··· 290 313 su ocaml -c "bash -xe tools/ci/actions/runner.sh install" 291 314 - name: Test in prefix 292 315 run: | 293 - su ocaml -c "bash -xe tools/ci/actions/runner.sh test-in-prefix" 316 + MAKE_ARG=-j su ocaml -c "bash -xe tools/ci/actions/runner.sh test-in-prefix" 317 + - name: Test in prefix (alternate configuration) 318 + if: ${{ needs.config.outputs.full-matrix == 'true' }} 319 + run: | 320 + MAKE_ARG=-j su ocaml -c "bash -xe tools/ci/actions/runner.sh re-test-in-prefix"
+22
Changes
··· 82 82 normalised on both Windows and Unix. 83 83 (David Allsopp, review by Jonah Beckford, Damien Doligez and Hugo Heuzard) 84 84 85 + - #14244: Added --with-relative-libdir which allows the runtime and the 86 + compilers to locate the Standard Library relative to where the binaries 87 + themselves are installed, removing the absolute path previously embedded in 88 + caml_standard_library_default. Executables linked with `ocamlc -custom` now 89 + always attempt to load bytecode from the executable itself, rather than first 90 + trying `argv[0]`. 91 + (David Allsopp, review by Jonah Beckford, Antonin Décimo, Damien Doligez, 92 + Samuel Hym and Vincent Laviron) 93 + 85 94 - #12269, #12410, #13063: Fix unsafety, deadlocks, and/or leaks should 86 95 rare errors happen during domain creation and thread 87 96 creation/registration. ··· 334 343 (Gabriel Scherer, review by Nicolás Ojeda Bär and Florian Angeletti, 335 344 report by Kate Deplaix) 336 345 346 + - #14244: Add -set-runtime-default option to the compiler, allowing the default 347 + value of the Standard Library location used by the runtime to be overridden. 348 + (Antonin Décimo, review by David Allsopp, Jonah Beckford, Damien Doligez and 349 + Samuel Hym) 350 + 337 351 - #14190: `ocaml -e` now also processes `-init` (previously it was ignored). 338 352 (Emile Trotignon, review by David Allsopp and @ygrek) 339 353 ··· 414 428 stublibs subdirectory is no longer created, nor added to ld.conf, when 415 429 building OCaml with --disable-shared. 416 430 (David Allsopp, review by Jonah Beckford, Damien Doligez and Hugo Heuzard) 431 + 432 + - #14244: When targeting native Windows on Cygwin or MSYS2, preserve 433 + backslashes in the supplied `--prefix` (in particular, backslashes instead of 434 + slashes will then be displayed by `ocamlopt -config-var standard_library`). 435 + If the supplied prefix contains a slash, then it is normalised, as 436 + previously. 437 + (David Allsopp, review by Jonah Beckford, Antonin Décimo, Damien Doligez and 438 + Samuel Hym) 417 439 418 440 ### Bug fixes: 419 441
+26 -3
Makefile
··· 483 483 utils/config_main.ml: utils/config.generated.ml utils/config.common.ml 484 484 $(V_GEN)cat $^ > $@ 485 485 486 + ADDITIONAL_CONFIGURE_ARGS ?= 486 487 .PHONY: reconfigure 487 488 reconfigure: 488 - ac_read_git_config=true ./configure $(CONFIGURE_ARGS) 489 + ac_read_git_config=true ./configure $(CONFIGURE_ARGS) \ 490 + $(ADDITIONAL_CONFIGURE_ARGS) 489 491 490 492 utils/domainstate.ml: utils/domainstate.ml.c runtime/caml/domain_state.tbl 491 493 $(V_GEN)$(CPP) -I runtime/caml $< > $@ ··· 899 901 $(FLEXDLL_SOURCES) | $(BYTE_BINDIR)/flexlink$(EXE) $(OPT_BINDIR) 900 902 rm -f $(FLEXDLL_SOURCE_DIR)/flexlink.exe 901 903 $(MAKE) -C $(FLEXDLL_SOURCE_DIR) $(FLEXLINK_BUILD_ENV) \ 902 - OCAMLOPT='$(FLEXLINK_OCAMLOPT) -nostdlib -I ../stdlib' flexlink.exe 904 + OCAMLOPT='$(FLEXLINK_OCAMLOPT) $(USE_STDLIB) $(SET_RELATIVE_STDLIB)' \ 905 + flexlink.exe 903 906 cp $(FLEXDLL_SOURCE_DIR)/flexlink.exe $@ 904 907 rm -f $(OPT_BINDIR)/flexlink$(EXE) 905 908 cd $(OPT_BINDIR); $(LN) $(call ROOT_FROM, $(OPT_BINDIR))/$@ flexlink$(EXE) ··· 976 979 977 980 ocamlc_BYTECODE_LINKFLAGS = -compat-32 -g 978 981 982 + ifeq "$(IN_COREBOOT_CYCLE)" "true" 983 + ocamlc_BYTECODE_LINKFLAGS += -set-runtime-default standard_library_default=. 984 + endif 985 + 979 986 partialclean:: 980 987 rm -f ocamlc ocamlc.exe ocamlc.opt ocamlc.opt.exe 981 988 ··· 1404 1411 1405 1412 C_LITERAL = $(shell $(SAK) $(ENCODE_C_LITERAL) '$(1)') 1406 1413 1407 - runtime/build_config.h: $(ROOTDIR)/Makefile.config $(SAK) 1414 + runtime/build_config.h: $(ROOTDIR)/Makefile.config \ 1415 + $(ROOTDIR)/Makefile.build_config $(SAK) 1408 1416 $(V_GEN){ \ 1409 1417 echo '/* This file is generated from $(ROOTDIR)/Makefile.config */'; \ 1410 1418 printf '#define OCAML_STDLIB_DIR %s\n' \ ··· 1412 1420 echo '#define HOST "$(HOST)"'; \ 1413 1421 } > $@ 1414 1422 1423 + runtime/prims.$(O): runtime/build_config.h 1424 + 1415 1425 ## Runtime libraries and programs 1416 1426 1417 1427 runtime/ocamlrun$(EXE): runtime/prims.$(O) runtime/libcamlrun.$(A) ··· 1710 1720 $(MAKE) lex-allopt 1711 1721 1712 1722 ocamllex_BYTECODE_LINKFLAGS = -compat-32 1723 + 1724 + ifeq "$(IN_COREBOOT_CYCLE)" "true" 1725 + ocamllex_BYTECODE_LINKFLAGS += -set-runtime-default standard_library_default=. 1726 + endif 1713 1727 1714 1728 partialclean:: 1715 1729 rm -f lex/*.cm* lex/*.o lex/*.obj \ ··· 2016 2030 testsuite/tools/test_in_prefi%: CAMLC = $(BEST_OCAMLC) $(STDLIBFLAGS) 2017 2031 2018 2032 test_in_prefix_BYTECODE_LINKFLAGS += -custom 2033 + 2034 + ifeq "$(TARGET_LIBDIR_IS_RELATIVE)" "true" 2035 + # testsuite/tools/test_in_prefix cannot use a relative stdlib because it is run 2036 + # from testsuite/tools, not from the installation tree (the alternative would be 2037 + # to compile it directly with the installed compiler) 2038 + test_in_prefix_NATIVE_LINKFLAGS = 2039 + test_in_prefix_COMMON_LINKFLAGS = \ 2040 + -set-runtime-default 'standard_library_default=$(LIBDIR)' 2041 + endif 2019 2042 2020 2043 testsuite/tools/test_in_prefi%: CAMLOPT = $(BEST_OCAMLOPT) $(STDLIBFLAGS) 2021 2044
+12 -3
Makefile.build_config.in
··· 75 75 DEP_CC=@DEP_CC@ -MM 76 76 COMPUTE_DEPS=@compute_deps@ 77 77 78 + BUILD_PATH_LOGICAL = @srcdir_abs@ 79 + BUILD_PATH_PHYSICAL = @srcdir_abs_real@ 80 + BUILD_MAP_FLAGS = @build_map_flags@ 81 + BUILD_MAP_CFLAGS = $(foreach flag, $(BUILD_MAP_FLAGS), \ 82 + $(call QUOTE_SINGLE,$(flag)$(BUILD_PATH_LOGICAL)=+build) \ 83 + $(if $(BUILD_PATH_PHYSICAL), \ 84 + $(call $(QUOTE_SINGLE),$(flag)$(BUILD_PATH_PHYSICAL)=+build))) 85 + 78 86 # Default flags to use to compile C files 79 - OC_CFLAGS = @oc_cflags@ 87 + OC_CFLAGS = @oc_cflags@ $(BUILD_MAP_CFLAGS) 80 88 81 89 # Flags to use when compiling C files to be linked with bytecode 82 - OC_BYTECODE_CFLAGS = @oc_bytecode_cflags@ 90 + OC_BYTECODE_CFLAGS = @oc_bytecode_cflags@ $(BUILD_MAP_CFLAGS) 83 91 84 92 # Flags to use when compiling C files to be linked with native code 85 - OC_NATIVE_CFLAGS = @oc_native_cflags@ 93 + OC_NATIVE_CFLAGS = @oc_native_cflags@ $(BUILD_MAP_CFLAGS) 86 94 87 95 # The submodules should be searched *before* any other external -I paths 88 96 OC_INCLUDES = $(addprefix -I $(ROOTDIR)/, \ ··· 143 151 144 152 ### Where to look for the standard library on target 145 153 TARGET_LIBDIR=@TARGET_LIBDIR@ 154 + TARGET_LIBDIR_IS_RELATIVE=@target_libdir_is_relative@ 146 155 147 156 unix_directory = @unix_directory@ 148 157 unix_library = @unix_library@
+23
Makefile.common
··· 29 29 SPACE := $(EMPTY) $(EMPTY) 30 30 # $( ) suppresses warning from the alignments in the V_ macros below 31 31 $(SPACE) := 32 + HASH := \# 32 33 33 34 ifeq "$(UNIX_OR_WIN32)" "win32" 34 35 DIR_SEP := \$ # There must a space following the $ ··· 37 38 DIR_SEP = / 38 39 CONVERT_PATH = $(strip $(1)) 39 40 endif 41 + 42 + QUOTE_SINGLE = '$(subst ','\'',$(1))' 40 43 41 44 V ?= 0 42 45 ··· 175 178 ifeq "$(FUNCTION_SECTIONS)" "true" 176 179 OPTCOMPFLAGS += -function-sections 177 180 endif 181 + 182 + ifeq "$(TARGET_LIBDIR_IS_RELATIVE)" "true" 183 + SRCDIR_ENCODED = $(subst =,%+,$(subst :,%.,$(subst %,%$(HASH),$(SRCDIR_ABS)))) 184 + SRCDIR_ABS_REAL := $(shell realpath $(SRCDIR_ABS) 2>/dev/null) 185 + SRCDIR_REAL_ENCODED = \ 186 + $(subst =,%+,$(subst :,%.,$(subst %,%$(HASH),$(SRCDIR_ABS_REAL)))) 187 + BUILD_PATH_PREFIX_MAP ?= 188 + export BUILD_PATH_PREFIX_MAP := \ 189 + $(BUILD_PATH_PREFIX_MAP)$\ 190 + :.=$(SRCDIR_ENCODED)$\ 191 + $(if $(SRCDIR_REAL_ENCODED),:.=$(SRCDIR_REAL_ENCODED)) 192 + endif # ifeq "$(TARGET_LIBDIR_IS_RELATIVE)" "true" 193 + 194 + # Allow Makefile.cross to override the Standard Library default for the compiler 195 + # itself. 196 + HOST_LIBDIR ?= $(TARGET_LIBDIR) 197 + 198 + OC_COMMON_LINKFLAGS += \ 199 + -set-runtime-default \ 200 + $(call QUOTE_SINGLE,standard_library_default=$(HOST_LIBDIR)) 178 201 179 202 # The rule to compile C files 180 203
+8 -1
Makefile.cross
··· 40 40 41 41 CROSS_OVERRIDES=OCAMLRUN=ocamlrun NEW_OCAMLRUN=ocamlrun \ 42 42 BOOT_OCAMLLEX=ocamllex OCAMLYACC=ocamlyacc 43 + # The cross-compiler is linked as build/bin/ocamlopt -o cross/bin/ocamlopt 44 + # Config.standard_library_default for cross/bin/ocamlopt would by default be the 45 + # value for build/bin/ocamlopt (i.e. build/lib/ocaml), which is not what is 46 + # wanted. When linking the cross-compiler itself, therefore, this default must 47 + # be overridden with -set-runtime-default so that cross/bin/ocamlopt instead has 48 + # cross/lib/ocaml for Config.standard_library_default 43 49 CROSS_COMPILER_OVERRIDES=$(CROSS_OVERRIDES) CAMLC=ocamlc CAMLOPT=ocamlopt \ 44 - BEST_OCAMLC=ocamlc BEST_OCAMLOPT=ocamlopt BEST_OCAMLLEX=ocamllex 50 + BEST_OCAMLC=ocamlc BEST_OCAMLOPT=ocamlopt BEST_OCAMLLEX=ocamllex \ 51 + HOST_LIBDIR="$(LIBDIR)" 45 52 CROSS_COMPILERLIBS_OVERRIDES=$(CROSS_OVERRIDES) CAMLC=ocamlc \ 46 53 CAMLOPT="$(ROOTDIR)/ocamlopt.opt$(EXE) $(STDLIBFLAGS)" 47 54
+1
appveyor.yml
··· 41 41 matrix: 42 42 - PORT: mingw64 43 43 BOOTSTRAP_FLEXDLL: true 44 + RELOCATABLE: true 44 45 # OCaml 5.0 does not yet support MSVC 45 46 # - PORT: msvc64 46 47 # BOOTSTRAP_FLEXDLL: false
+12
asmcomp/asmlink.ml
··· 198 198 crc_interfaces defined 199 199 200 200 let make_startup_file ~ppf_dump units_list ~crc_interfaces = 201 + let need_stdlib = 202 + let needs_stdlib ({ui_need_stdlib; _}, _, _) = ui_need_stdlib in 203 + List.exists needs_stdlib units_list 204 + in 201 205 let compile_phrase p = Asmgen.compile_phrase ~ppf_dump p in 202 206 Location.input_name := "caml_startup"; (* set name of "current" input *) 203 207 Compilenv.reset "_startup"; ··· 224 228 Array.iteri 225 229 (fun i name -> compile_phrase (Cmm_helpers.predef_exception i name)) 226 230 Runtimedef.builtin_exceptions; 231 + if need_stdlib then begin 232 + let standard_library_default = 233 + Option.value ~default:Config.standard_library_default 234 + !Clflags.standard_library_default in 235 + compile_phrase 236 + (Cmm_helpers.emit_global_string_constant 237 + "caml_standard_library_nat" standard_library_default) 238 + end; 227 239 compile_phrase (Cmm_helpers.global_table name_list); 228 240 let globals_map = make_globals_map units_list ~crc_interfaces in 229 241 compile_phrase (Cmm_helpers.globals_map globals_map);
+4
asmcomp/asmpackager.ml
··· 217 217 else 218 218 Clambda (get_approx ui) 219 219 in 220 + let ui_need_stdlib = 221 + List.exists (function {ui_need_stdlib; _} -> ui_need_stdlib) units 222 + in 220 223 Export_info_for_pack.clear_import_state (); 221 224 let pkg_infos = 222 225 { ui_name = ui.ui_name; ··· 239 242 List.exists (fun info -> info.ui_force_link) units; 240 243 ui_export_info; 241 244 ui_for_pack = None; 245 + ui_need_stdlib; 242 246 } in 243 247 Compilenv.write_unit_info pkg_infos cmxfile 244 248
+3
asmcomp/cmm_helpers.ml
··· 2660 2660 in 2661 2661 Cdata data_items 2662 2662 2663 + let emit_global_string_constant name value = 2664 + Cdata (emit_string_constant (name, Global) value []) 2665 + 2663 2666 (* Header for a plugin *) 2664 2667 2665 2668 let plugin_header units =
+3
asmcomp/cmm_helpers.mli
··· 628 628 (** Generate data for a predefined exception *) 629 629 val predef_exception: int -> string -> phrase 630 630 631 + (** Generate data for a global string constant *) 632 + val emit_global_string_constant: string -> string -> phrase 633 + 631 634 val plugin_header: (Cmx_format.unit_infos * Digest.BLAKE128.t) list -> phrase 632 635 633 636 (** Emit constant symbols *)
boot/ocamlc

This is a binary file and will not be displayed.

boot/ocamllex

This is a binary file and will not be displayed.

+2 -1
bytecomp/bytegen.ml
··· 439 439 | Ostype_unix -> "ostype_unix" 440 440 | Ostype_win32 -> "ostype_win32" 441 441 | Ostype_cygwin -> "ostype_cygwin" 442 - | Backend_type -> "backend_type" in 442 + | Backend_type -> "backend_type" 443 + | Standard_library_default -> "standard_library_default" in 443 444 Kccall(Printf.sprintf "caml_sys_const_%s" const_name, 1) 444 445 | Pisint -> Kisint 445 446 | Pisout -> Kisout
+97 -28
bytecomp/bytelink.ml
··· 19 19 open Config 20 20 open Cmo_format 21 21 22 + module String = Misc.Stdlib.String 22 23 module Compunit = Symtable.Compunit 23 24 24 25 module Dep = struct ··· 201 202 202 203 (* Link in a compilation unit *) 203 204 204 - let link_compunit output_fun currpos_fun inchan file_name compunit = 205 + let link_compunit accu output_fun currpos_fun inchan file_name compunit = 205 206 check_consistency file_name compunit; 206 207 seek_in inchan compunit.cu_pos; 207 208 let code_block = ··· 227 228 debug_info := (currpos_fun(), debug_event_list, debug_dirs) :: !debug_info 228 229 end; 229 230 output_fun code_block; 230 - if !Clflags.link_everything then 231 - List.iter Symtable.require_primitive compunit.cu_primitives 231 + let fold_primitive needs_stdlib name = 232 + if !Clflags.link_everything then 233 + Symtable.require_primitive name; 234 + (needs_stdlib || name = "%standard_library_default") 235 + in 236 + List.fold_left fold_primitive accu compunit.cu_primitives 232 237 233 238 (* Link in a .cmo file *) 234 239 235 - let link_object output_fun currpos_fun file_name compunit = 236 - let inchan = open_in_bin file_name in 237 - try 238 - link_compunit output_fun currpos_fun inchan file_name compunit; 239 - close_in inchan 240 - with 241 - Symtable.Error msg -> 242 - close_in inchan; raise(Error(Symbol_error(file_name, msg))) 243 - | x -> 244 - close_in inchan; raise x 240 + let link_object accu output_fun currpos_fun file_name compunit = 241 + In_channel.with_open_bin file_name @@ fun inchan -> 242 + try link_compunit accu output_fun currpos_fun inchan file_name compunit 243 + with Symtable.Error msg -> raise(Error(Symbol_error(file_name, msg))) 245 244 246 245 (* Link in a .cma file *) 247 246 248 - let link_archive output_fun currpos_fun file_name units_required = 249 - let inchan = open_in_bin file_name in 250 - try 251 - List.iter 252 - (fun cu -> 247 + let link_archive accu output_fun currpos_fun file_name units_required = 248 + In_channel.with_open_bin file_name @@ fun inchan -> 249 + List.fold_left 250 + (fun accu cu -> 253 251 let n = Compunit.name cu.cu_name in 254 252 let name = file_name ^ "(" ^ n ^ ")" in 255 253 try 256 - link_compunit output_fun currpos_fun inchan name cu 254 + link_compunit accu output_fun currpos_fun inchan name cu 257 255 with Symtable.Error msg -> 258 256 raise(Error(Symbol_error(name, msg)))) 259 - units_required; 260 - close_in inchan 261 - with x -> close_in inchan; raise x 257 + accu units_required 262 258 263 259 (* Link in a .cmo or .cma file *) 264 260 265 - let link_file output_fun currpos_fun = function 261 + let link_file output_fun currpos_fun accu = function 266 262 Link_object(file_name, unit) -> 267 - link_object output_fun currpos_fun file_name unit 263 + link_object accu output_fun currpos_fun file_name unit 268 264 | Link_archive(file_name, units) -> 269 - link_archive output_fun currpos_fun file_name units 265 + link_archive accu output_fun currpos_fun file_name units 266 + 267 + let link_files output_fun currpos_fun = 268 + List.fold_left (link_file output_fun currpos_fun) false 270 269 271 270 (* Output the debugging information *) 272 271 (* Format is: ··· 340 339 let bindir_start = String.index buffer '\n' + 1 in 341 340 let bindir_end = String.index_from buffer bindir_start '\000' in 342 341 let bindir = String.sub buffer bindir_start (bindir_end - bindir_start) in 342 + let bindir = 343 + if bindir = Filename.current_dir_name then 344 + Filename.dirname Sys.executable_name 345 + else 346 + bindir in 343 347 let executable_offset = bindir_end + 2 in 344 348 let launcher = 345 349 let kind = String.sub buffer 0 (bindir_start - 1) in ··· 496 500 let output_fun buf = 497 501 Out_channel.output_bigarray outchan buf 0 (Bigarray.Array1.dim buf) 498 502 and currpos_fun () = pos_out outchan - start_code in 499 - List.iter (link_file output_fun currpos_fun) tolink; 503 + let needs_stdlib = 504 + link_files output_fun currpos_fun tolink 505 + in 500 506 if check_dlls then Dll.close_all_dlls(); 501 507 (* The final STOP instruction *) 502 508 output_byte outchan Opcodes.opSTOP; ··· 519 525 ~filename:final_name ~kind:"bytecode executable" 520 526 outchan (Symtable.initial_global_table()); 521 527 Bytesections.record toc_writer DATA; 528 + (* -custom executables don't need OSLD sections - the correct value is 529 + already included in the runtime. *) 530 + if standalone && needs_stdlib then begin 531 + (* OCaml Standard Library Default location *) 532 + let standard_library_default = 533 + Option.value 534 + ~default:Config.standard_library_default 535 + !Clflags.standard_library_default 536 + in 537 + output_string outchan standard_library_default; 538 + Bytesections.record toc_writer OSLD 539 + end; 522 540 (* The map of global identifiers *) 523 541 Symtable.output_global_map outchan; 524 542 Bytesections.record toc_writer SYMB; ··· 590 608 Bytesections.write_toc_and_trailer toc_writer; 591 609 ) 592 610 611 + (* [c_string_literal_of_string s] returns the C literal string representation of 612 + [s], suitable for embedding in a C source file with type [char_os *]. The 613 + result includes the quote markers. *) 614 + let c_string_literal_of_string s = 615 + let b = Buffer.create (String.length s * 2) in 616 + let utf16le = Bytes.create 4 in 617 + let escape u = 618 + match Uchar.to_int u with 619 + (* Characters with C escape sequences *) 620 + | 000 (* '\0' *) -> Buffer.add_string b "\\000" 621 + | 009 (* '\t' *) -> Buffer.add_string b "\\t" 622 + | 010 (* '\n' *) -> Buffer.add_string b "\\n" 623 + | 013 (* '\r' *) -> Buffer.add_string b "\\r" 624 + | 034 (* '\"' *) -> Buffer.add_string b "\\\"" 625 + | 092 (* '\\' *) -> Buffer.add_string b "\\\\" 626 + (* Most C compilers will have no problem processing UTF-8 in the strings 627 + with the characters above converted to their C representations. On 628 + Windows, where the string is [wchar_t *], all characters for which 629 + iswprint returns 0 are escaped using the extended [\x] notation. *) 630 + | c when Config.target_win32 && (c < 32 (* ' ' *) || c >= 127) -> 631 + (* Convert u to UTF-16LE, allowing for surrogate pairs *) 632 + let len = Bytes.set_utf_16le_uchar utf16le 0 u in 633 + for i = 1 to len / 2 do 634 + Printf.bprintf b "\\x%04x" (Bytes.get_uint16_le utf16le ((i - 1) * 2)) 635 + done 636 + | _ -> 637 + Buffer.add_utf_8_uchar b u 638 + in 639 + if Config.target_win32 then 640 + Buffer.add_char b 'L'; 641 + Buffer.add_char b '"'; 642 + Seq.iter escape (String.to_utf_8_seq s); 643 + Buffer.add_char b '"'; 644 + Buffer.contents b 645 + 646 + let emit_runtime_standard_library_default outchan = 647 + let stdlib = 648 + let default = Config.standard_library_default in 649 + Option.value ~default !Clflags.standard_library_default in 650 + let literal = c_string_literal_of_string stdlib in 651 + Printf.fprintf outchan 652 + "const char_os * caml_runtime_standard_library_default = %s;\n" literal 653 + 593 654 (* Output a bytecode executable as a C file *) 594 655 595 656 let link_bytecode_as_c tolink outfile with_main = ··· 613 674 #include <caml/sys.h> 614 675 #include <caml/misc.h> 615 676 677 + const enum caml_byte_program_mode caml_byte_program_mode = EMBEDDED; 678 + 616 679 static int caml_code[] = { 617 680 |}; 618 681 Symtable.init(); ··· 622 685 output_code_string outchan code; 623 686 currpos := !currpos + (Bigarray.Array1.dim code) 624 687 and currpos_fun () = !currpos in 625 - List.iter (link_file output_fun currpos_fun) tolink; 688 + ignore (link_files output_fun currpos_fun tolink); 626 689 (* The final STOP instruction *) 627 690 Printf.fprintf outchan "\n0x%x};\n" Opcodes.opSTOP; 628 691 (* The table of global data *) ··· 650 713 }; 651 714 652 715 |}; 716 + emit_runtime_standard_library_default outchan; 653 717 (* The table of primitives *) 654 718 Symtable.output_primitive_table outchan; 655 719 (* The entry point *) ··· 657 721 output_string outchan {| 658 722 int main_os(int argc, char_os **argv) 659 723 { 660 - caml_byte_program_mode = COMPLETE_EXE; 661 724 caml_startup_code(caml_code, sizeof(caml_code), 662 725 caml_data, sizeof(caml_data), 663 726 caml_sections, sizeof(caml_sections), ··· 799 862 extern "C" { 800 863 #endif 801 864 865 + #define CAML_INTERNALS 802 866 #define CAML_INTERNALS_NO_PRIM_DECLARATIONS 867 + 803 868 #include <caml/mlvalues.h> 869 + #include <caml/startup.h> 870 + 871 + const enum caml_byte_program_mode caml_byte_program_mode = APPENDED; 804 872 805 873 |}; 806 874 Symtable.output_primitive_table poc; 875 + emit_runtime_standard_library_default poc; 807 876 output_string poc {| 808 877 #ifdef __cplusplus 809 878 }
+3
bytecomp/bytesections.ml
··· 26 26 | DBUG (** debug info *) 27 27 | DLLS (** dll names *) 28 28 | DLPT (** dll paths *) 29 + | OSLD (** OCaml Standard Library Default location *) 29 30 | PRIM (** primitives names *) 30 31 | RNTM (** The path to the bytecode interpreter (use_runtime mode) *) 31 32 | SYMB (** global identifiers *) ··· 37 38 | "DLPT" -> DLPT 38 39 | "DLLS" -> DLLS 39 40 | "DATA" -> DATA 41 + | "OSLD" -> OSLD 40 42 | "PRIM" -> PRIM 41 43 | "SYMB" -> SYMB 42 44 | "DBUG" -> DBUG ··· 52 54 | DLPT -> "DLPT" 53 55 | DLLS -> "DLLS" 54 56 | DATA -> "DATA" 57 + | OSLD -> "OSLD" 55 58 | PRIM -> "PRIM" 56 59 | SYMB -> "SYMB" 57 60 | DBUG -> "DBUG"
+1
bytecomp/bytesections.mli
··· 27 27 | DBUG (** debug info *) 28 28 | DLLS (** dll names *) 29 29 | DLPT (** dll paths *) 30 + | OSLD (** OCaml Standard Library Default location *) 30 31 | PRIM (** primitives names *) 31 32 | RNTM (** The path to the bytecode interpreter (use_runtime mode) *) 32 33 | SYMB (** global identifiers *)
+334 -37
configure
··· 800 800 build_vendor 801 801 build_cpu 802 802 build 803 + build_map_flags 804 + srcdir_abs_real 805 + srcdir_abs 806 + target_libdir_is_relative 803 807 ar_supports_response_files 804 808 QS 805 809 TARGET_LIBDIR 806 810 ocaml_libdir 807 811 ocaml_bindir 812 + ocaml_prefix 808 813 compute_deps 809 814 build_libraries_manpages 810 815 PACKLD ··· 851 856 build_ocamltex 852 857 build_ocamldebug 853 858 with_debugger 859 + as_is_cc 854 860 as_has_debug_prefix_map 855 861 cc_has_debug_prefix_map 856 862 unix_directory ··· 1044 1050 enable_flat_float_array 1045 1051 enable_function_sections 1046 1052 enable_mmap_map_stack 1053 + with_relative_libdir 1047 1054 with_afl 1048 1055 with_flexdll 1049 1056 with_winpthreads_msvc ··· 1774 1781 --with-additional-stublibsdir 1775 1782 additional directory for searching for bytecode stub 1776 1783 libraries 1784 + --with-relative-libdir location of the Standard Library, specified relative 1785 + to --bindir (if no argument is given to 1786 + --with-relative-libdir, defaults to ../lib/ocaml) 1777 1787 --with-afl use the AFL fuzzer 1778 1788 --with-flexdll bootstrap FlexDLL from the given sources 1779 1789 --with-winpthreads-msvc build winpthreads (only for the MSVC port) from the ··· 3371 3381 unix_library="" 3372 3382 unix_directory="" 3373 3383 diff_supports_color=false 3384 + target_libdir_is_relative=false 3385 + srcdir_abs='' 3386 + srcdir_abs_real='' 3387 + build_map_flags='' 3374 3388 3375 3389 # Information about the package 3376 3390 ··· 3525 3539 3526 3540 3527 3541 3542 + 3528 3543 # TODO: rename this variable 3544 + 3545 + 3546 + 3547 + 3548 + 3529 3549 3530 3550 3531 3551 ··· 3786 3806 ac_tool_prefix=$target_alias- 3787 3807 fi 3788 3808 3809 + # $cygwin_build_env=true if the build is taking place in any kind of Cygwin-like 3810 + # environment (which may include cross-compiling _from_ Cygwin) 3811 + # All patterns end with * (cf. build-aux/config.sub) 3812 + # 3813 + # In Cygwin itself, the mingw-w64 compilers are cross-compilers 3814 + # (host=x86_64-pc-cygwin; target=*-w64-mingw32) and $build when running from 3815 + # within Cygwin is always *-pc-cygwin. 3816 + # 3817 + # In MSYS2, the mingw-w64 compilers are normal host compilers, which MSYS2 makes 3818 + # available through different Environments (similar to the Microsoft Visual 3819 + # Studio Tools Command Prompts; see https://www.msys2.org/docs/environments/). 3820 + # It is possible to use MSYS2's "Cygwin" gcc (the equivalent of compiling native 3821 + # Cygwin), in which case $build is *-*-cygwin (some older MSYS2 installations 3822 + # may report the legacy *-*-msys*) 3823 + # The mingw-w64 Environments manually set $build to *-w64-mingw32, but the 3824 + # _native_ value inferred by config.guess (which uses uname -s) will be 3825 + # *-pc-mingw32 (for the 32-bit _target_ environments, even though MSYS2 is a 3826 + # 64-bit build environment) and *-pc-mingw64 (for the 64-bit _target_ 3827 + # environments). 3828 + # 3829 + # This leads to the four patterns below, all of which imply that the build is 3830 + # taking place on a system where Cygwin's utilities (cygpath, etc.) can be 3831 + # expected to be found and its semantics (CYGWIN=winsymlinks:native, etc.) be 3832 + # expected to apply. 3833 + # 3834 + # Note that although build=x86_64-pc-mingw64 will be accepted here, it is highly 3835 + # likely that that's a misconfigured environment, and the script will 3836 + # subsequently fail if host has not been altered to x86_64-w64-mingw32. 3837 + case $build in #( 3838 + *-*-cygwin*|*-*-msys*|*-*-mingw32*|*-*-mingw64*) : 3839 + cygwin_build_env=true ;; #( 3840 + *) : 3841 + cygwin_build_env=false ;; 3842 + esac 3843 + 3789 3844 # Ensure that AC_CONFIG_LINKS will either create symlinks which are compatible 3790 3845 # with native Windows (i.e. NTFS symlinks, not WSL or Cygwin-emulated ones) or 3791 3846 # use its fallback mechanisms. Native Windows versions of ocamlc/ocamlopt cannot 3792 3847 # interpret either WSL or Cygwin-emulated symlinks. 3793 - case $host in #( 3794 - *-pc-windows|*-w64-mingw32*) : 3848 + case $cygwin_build_env,$host in #( 3849 + true,*-pc-windows|true,*-w64-mingw32*) : 3795 3850 ac_config_commands="$ac_config_commands native-symlinks" 3796 3851 ;; #( 3797 3852 *) : ··· 4316 4371 if test ${enable_mmap_map_stack+y} 4317 4372 then : 4318 4373 enableval=$enable_mmap_map_stack; 4374 + fi 4375 + 4376 + 4377 + 4378 + # Check whether --with-relative-libdir was given. 4379 + if test ${with_relative_libdir+y} 4380 + then : 4381 + withval=$with_relative_libdir; case $withval in #( 4382 + no) : 4383 + bindir_to_libdir='' ;; #( 4384 + yes) : 4385 + bindir_to_libdir="..${default_separator}lib${default_separator}ocaml" ;; #( 4386 + *) : 4387 + bindir_to_libdir="$withval" ;; 4388 + esac 4389 + else $as_nop 4390 + bindir_to_libdir='' 4319 4391 fi 4320 4392 4321 4393 ··· 15114 15186 # See https://lists.gnu.org/archive/html/autoconf/2019-07/msg00002.html 15115 15187 # for the detailed explanation. 15116 15188 15117 - ocamlsrcdir=$(unset CDPATH; cd -- "$srcdir" && printf %sX "$PWD") || fail 15118 - ocamlsrcdir=${ocamlsrcdir%X} 15189 + srcdir_abs=$(unset CDPATH; cd -- "$srcdir" && printf %sX "$PWD") || fail 15190 + srcdir_abs=${srcdir_abs%X} 15119 15191 15120 - case $host in #( 15121 - *-w64-mingw32*|*-pc-windows) : 15192 + case $cygwin_build_env,$host in #( 15193 + true,*-w64-mingw32*|true,*-pc-windows) : 15122 15194 15123 15195 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a workable solution for ln -sf" >&5 15124 15196 printf %s "checking for a workable solution for ln -sf... " >&6; } ··· 15132 15204 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ln" >&5 15133 15205 printf "%s\n" "$ln" >&6; } 15134 15206 15135 - ocamlsrcdir="$(LC_ALL=C.UTF-8 cygpath -w -- "$ocamlsrcdir")" ;; #( 15207 + ocamlsrcdir="$(LC_ALL=C.UTF-8 cygpath -w -- "$srcdir_abs")" ;; #( 15136 15208 *) : 15137 - ln='ln -sf' ;; 15209 + ln='ln -sf' 15210 + ocamlsrcdir="$srcdir_abs" ;; 15138 15211 esac 15139 15212 15140 15213 # Whether ar supports @FILE arguments ··· 16066 16139 if test x"$build" != x"$host" 16067 16140 then : 16068 16141 16069 - case $build in #( 16070 - *-pc-msys|*-*-cygwin) : 16071 - flexlink_where="$(cmd /c "$flexlink" -where 2>/dev/null)" 16072 - if test -z "$flexlink_where" 16142 + if $cygwin_build_env 16143 + then : 16144 + flexlink_where="$(cmd /c "$flexlink" -where 2>/dev/null)" 16145 + if test -z "$flexlink_where" 16073 16146 then : 16074 16147 as_fn_error $? "$flexlink is not executable from a native Win32 process" "$LINENO" 5 16075 - fi ;; #( 16076 - *) : 16077 - ;; 16078 - esac 16148 + 16149 + fi 16150 + 16151 + fi 16079 16152 16080 16153 fi 16081 16154 ··· 17754 17827 17755 17828 17756 17829 # Checks for header files 17830 + 17831 + ac_fn_c_check_header_compile "$LINENO" "libgen.h" "ac_cv_header_libgen_h" "$ac_includes_default" 17832 + if test "x$ac_cv_header_libgen_h" = xyes 17833 + then : 17834 + printf "%s\n" "#define HAS_LIBGEN_H 1" >>confdefs.h 17835 + 17836 + fi 17757 17837 17758 17838 ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default" 17759 17839 if test "x$ac_cv_header_pthread_np_h" = xyes ··· 19448 19528 # to avoiding forking a C compiler process for each compilation by ocamlopt. 19449 19529 # Both AS and ASPP can be overridden by the user. 19450 19530 19451 - default_as="$CC -c" 19452 - default_aspp="$CC -c" 19531 + as_is_cc=true 19532 + default_as='' 19453 19533 19454 19534 case $as_target,$ocaml_cc_vendor in #( 19455 19535 *-*-linux*,gcc-*) : 19456 19536 case $as_cpu in #( 19457 19537 x86_64|arm*|aarch64*|i[3-6]86|riscv*) : 19458 - default_as="${toolpref}as" ;; #( 19538 + default_as="${toolpref}as" 19539 + as_is_cc=false ;; #( 19459 19540 *) : 19460 19541 ;; 19461 19542 esac ;; #( 19543 + *-*-cygwin,gcc-*) : 19544 + default_as="${toolpref}as" 19545 + as_is_cc=false ;; #( 19462 19546 i686-pc-windows,*) : 19463 19547 default_as="ml -nologo -coff -Cp -c -Fo" 19464 - default_aspp="$default_as" ;; #( 19548 + default_aspp="$default_as" 19549 + as_is_cc=false ;; #( 19465 19550 x86_64-pc-windows,*) : 19466 19551 default_as="ml64 -nologo -Cp -c -Fo" 19467 - default_aspp="$default_as" ;; #( 19552 + default_aspp="$default_as" 19553 + as_is_cc=false ;; #( 19468 19554 *-*-darwin*,clang-*) : 19469 - default_as="$default_as -Wno-trigraphs" 19555 + default_as="$CC -c -Wno-trigraphs" 19470 19556 default_aspp="$default_as" ;; #( 19471 19557 *) : 19472 19558 ;; 19473 19559 esac 19474 19560 19561 + if test -z "$default_as" 19562 + then : 19563 + default_as="$CC -c" 19564 + fi 19565 + if test -z "$default_aspp" 19566 + then : 19567 + default_aspp="$CC -c" 19568 + fi 19569 + 19475 19570 if test "$with_pic" 19476 19571 then : 19477 19572 fpic=true ··· 21389 21484 21390 21485 ## -fdebug-prefix-map support by the C compiler 21391 21486 case $ocaml_cc_vendor,$target in #( 21392 - *,*-w64-mingw32*) : 21393 - cc_has_debug_prefix_map=false ;; #( 21394 21487 *,*-pc-windows) : 21395 21488 cc_has_debug_prefix_map=false ;; #( 21396 21489 xlc*,powerpc-ibm-aix*) : ··· 21440 21533 ;; 21441 21534 esac 21442 21535 21536 + ## -ffile-prefix-map support by the C compiler - used in the build, not by 21537 + ## the compiler 21538 + if test x"$bindir_to_libdir" != 'x' 21539 + then : 21540 + srcdir_abs_real="$(realpath "$srcdir_abs" 2>/dev/null)" 21541 + if test x"$srcdir_abs_real" = "x$srcdir_abs" 21542 + then : 21543 + srcdir_abs_real='' 21544 + fi 21545 + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags_$warn_error_flag_-Wa,--debug-prefix-map=old=new" | $as_tr_sh` 21546 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -Wa,--debug-prefix-map=old=new" >&5 21547 + printf %s "checking whether the C compiler accepts -Wa,--debug-prefix-map=old=new... " >&6; } 21548 + if eval test \${$as_CACHEVAR+y} 21549 + then : 21550 + printf %s "(cached) " >&6 21551 + else $as_nop 21552 + 21553 + ax_check_save_flags=$CFLAGS 21554 + CFLAGS="$CFLAGS $warn_error_flag -Wa,--debug-prefix-map=old=new" 21555 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext 21556 + /* end confdefs.h. */ 21557 + 21558 + int 21559 + main (void) 21560 + { 21561 + 21562 + ; 21563 + return 0; 21564 + } 21565 + _ACEOF 21566 + if ac_fn_c_try_compile "$LINENO" 21567 + then : 21568 + eval "$as_CACHEVAR=yes" 21569 + else $as_nop 21570 + eval "$as_CACHEVAR=no" 21571 + fi 21572 + rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext 21573 + CFLAGS=$ax_check_save_flags 21574 + fi 21575 + eval ac_res=\$$as_CACHEVAR 21576 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 21577 + printf "%s\n" "$ac_res" >&6; } 21578 + if eval test \"x\$"$as_CACHEVAR"\" = x"yes" 21579 + then : 21580 + build_map_flags='-Wa,--debug-prefix-map=' 21581 + else $as_nop 21582 + : 21583 + fi 21584 + 21585 + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags_$warn_error_flag_-ffile-prefix-map=old=new" | $as_tr_sh` 21586 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -ffile-prefix-map=old=new" >&5 21587 + printf %s "checking whether the C compiler accepts -ffile-prefix-map=old=new... " >&6; } 21588 + if eval test \${$as_CACHEVAR+y} 21589 + then : 21590 + printf %s "(cached) " >&6 21591 + else $as_nop 21592 + 21593 + ax_check_save_flags=$CFLAGS 21594 + CFLAGS="$CFLAGS $warn_error_flag -ffile-prefix-map=old=new" 21595 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext 21596 + /* end confdefs.h. */ 21597 + 21598 + int 21599 + main (void) 21600 + { 21601 + 21602 + ; 21603 + return 0; 21604 + } 21605 + _ACEOF 21606 + if ac_fn_c_try_compile "$LINENO" 21607 + then : 21608 + eval "$as_CACHEVAR=yes" 21609 + else $as_nop 21610 + eval "$as_CACHEVAR=no" 21611 + fi 21612 + rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext 21613 + CFLAGS=$ax_check_save_flags 21614 + fi 21615 + eval ac_res=\$$as_CACHEVAR 21616 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 21617 + printf "%s\n" "$ac_res" >&6; } 21618 + if eval test \"x\$"$as_CACHEVAR"\" = x"yes" 21619 + then : 21620 + build_map_flags="$build_map_flags -ffile-prefix-map=" 21621 + else $as_nop 21622 + if $cc_has_debug_prefix_map 21623 + then : 21624 + build_map_flags="$build_map_flags -fdebug-prefix-map=" 21625 + fi 21626 + fi 21627 + 21628 + fi 21629 + 21443 21630 ## Does stat support nanosecond precision 21444 21631 21445 21632 stat_has_ns_precision=false ··· 24148 24335 libdir="$libdir"/ocaml 24149 24336 fi 24150 24337 24151 - if test x"$TARGET_LIBDIR" = x 24152 - then : 24153 - TARGET_LIBDIR="$libdir" 24154 - fi 24155 - 24156 24338 if test x"$mandir" = x'${datarootdir}/man' 24157 24339 then : 24158 24340 mandir='${prefix}/man' ··· 24173 24355 *) : 24174 24356 ;; 24175 24357 esac 24358 + fi 24359 + 24360 + # Normalise $prefix, if necessary, on Windows. There are 9 variables to be 24361 + # considered: 24362 + # - $prefix and $exec_prefix. These are autoconf variables containing the values 24363 + # specified for --prefix and --exec-prefix respectively, or NONE if these 24364 + # flags were not given on the command line. These two variables are written to 24365 + # Makefile.config and are in _build_ format. On native Windows, the values 24366 + # must be suitable to pass to _both_ native Windows processes and Cygwin/MSYS2 24367 + # commands. The values are ultimately converted to Windows paths using slashes 24368 + # (i.e. C:/foo) 24369 + # - $bindir and $libdir. These similarly contain the values specified for 24370 + # --bindir and --libdir, or defaults relative to $exec_prefix otherwise. 24371 + # Unlike --prefix, values specified to configure for --bindir and --libdir are 24372 + # assumed to be suitable for both native Windows processes and Cygwin/MSYS2. 24373 + # These two variables ultimately end up in Makefile.config as $(BINDIR) and 24374 + # $(LIBDIR) and are used for installation commands only. 24375 + # - $ocaml_prefix, $ocaml_bindir and $ocaml_libdir are the _expanded_ values of 24376 + # $prefix, $bindir and $libdir so that the values can be inserted into OCaml 24377 + # strings (typically in utils/config.generated.ml). On Windows, these preserve 24378 + # the backslashes present in the value passed to --prefix. 24379 + # - $TARGET_BINDIR and $TARGET_LIBDIR. These are both precious environment 24380 + # variables (meaning their value is recorded by configure) but they default to 24381 + # $ocaml_bindir and $ocaml_libdir respectively. 24382 + ocaml_bindir="$bindir" 24383 + ocaml_libdir="$libdir" 24384 + ocaml_prefix="$prefix" 24385 + case $cygwin_build_env,$host in #( 24386 + true,*-w64-mingw32*|true,*-pc-windows) : 24387 + prefix="$(LC_ALL=C.UTF-8 cygpath -m "$prefix")" 24388 + if test "x${ocaml_prefix%%/*}" != "x$ocaml_prefix" 24389 + then : 24390 + # $prefix contained a slash - normalise it with cygpath. The rationale for 24391 + # this allows both `./configure --prefix $PWD/install` (which will be a 24392 + # Cygwin path) and also systems lazily using slashes instead of 24393 + # backslashes (i.e. C:/Backslashes/Scare/Us) to work. 24394 + ocaml_prefix="$prefix" 24176 24395 else $as_nop 24177 - case $build,$host in #( 24178 - *-*-cygwin,*-w64-mingw32*|*-*-cygwin,*-pc-windows) : 24179 - prefix="$(LC_ALL=C.UTF-8 cygpath -m "$prefix")" ;; #( 24396 + # $prefix was using backslashes - preserve these in the build, but 24397 + # continue to use slashes for the Makefile variables. 24398 + if test "x$bindir" = 'x${exec_prefix}/bin' 24399 + then : 24400 + ocaml_bindir='${exec_prefix}\bin' 24401 + else $as_nop 24402 + ocaml_bindir="$bindir" 24403 + fi 24404 + if test "x$libdir" = 'x${exec_prefix}/lib/ocaml' 24405 + then : 24406 + ocaml_libdir='${exec_prefix}\lib\ocaml' 24407 + else $as_nop 24408 + ocaml_libdir="$libdir" 24409 + fi 24410 + fi ;; #( 24180 24411 *) : 24181 24412 ;; 24182 24413 esac 24414 + 24415 + if test x"$libdir" = x'${exec_prefix}/lib/ocaml' 24416 + then : 24417 + if test x"$bindir_to_libdir" != 'x' 24418 + then : 24419 + ocaml_libdir="$bindir_to_libdir" 24420 + target_libdir_is_relative=true 24421 + case $cygwin_build_env,$host in #( 24422 + true,*-w64-mingw32*|true,*-pc-windows) : 24423 + build_bindir_to_libdir="$(LC_ALL=C.UTF-8 cygpath \ 24424 + "$bindir_to_libdir")" ;; #( 24425 + *) : 24426 + build_bindir_to_libdir="$bindir_to_libdir" ;; 24427 + esac 24428 + case $build_bindir_to_libdir in #( 24429 + ./*) : 24430 + libdir="$bindir${build_bindir_to_libdir#.}" ;; #( 24431 + ../*) : 24432 + libdir="$bindir/$build_bindir_to_libdir" ;; #( 24433 + *) : 24434 + as_fn_error $? "--with-relative-libdir requires an explicit relative path" "$LINENO" 5 ;; 24435 + esac 24436 + fi 24437 + else $as_nop 24438 + if test x"$bindir_to_libdir" != 'x' 24439 + then : 24440 + as_fn_error $? "--with-relative-libdir and --libdir cannot both be specified" "$LINENO" 5 24441 + fi 24442 + fi 24443 + 24444 + if test x"$bindir_to_libdir" != 'x' && test x"$TARGET_LIBDIR" != 'x' 24445 + then : 24446 + as_fn_error $? "--with-relative-libdir and TARGET_LIBDIR cannot both be specified" "$LINENO" 5 24183 24447 fi 24184 24448 24185 24449 # Define a few macros that were defined in config/m-nt.h ··· 24364 24628 24365 24629 saved_exec_prefix="$exec_prefix" 24366 24630 saved_prefix="$prefix" 24631 + prefix="$ocaml_prefix" 24367 24632 if test "x$prefix" = "xNONE" 24368 24633 then : 24369 24634 prefix="$ac_default_prefix" ··· 24373 24638 exec_prefix="$prefix" 24374 24639 fi 24375 24640 eval "exec_prefix=\"$exec_prefix\"" 24376 - eval "ocaml_bindir=\"$bindir\"" 24377 - eval "ocaml_libdir=\"$libdir\"" 24641 + # Set variables necessary to create utils/config.generated.ml and the two 24642 + # runtime-launch-info templates in stdlib. 24643 + # $ocaml_bindir is used for utils/config.generated.ml and is _empty_ if the 24644 + # compiler is configured with --with-relative-libdir (otherwise the path 24645 + # would be embedded in config.cmo) 24646 + # $HOST_BINDIR and $TARGET_BINDIR are used to generate the two 24647 + # runtime-launch-info files. $HOST_BINDIR is always the absolute path to the 24648 + # binary directory, in host format (i.e. potentially with backslashes on 24649 + # Windows). $TARGET_BINDIR can be specified by the caller when building 24650 + # cross-compilers, and the value then is used unaltered. Otherwise, 24651 + # $TARGET_BINDIR is set to '.' when the compiler is configured with 24652 + # --with-relative-libdir or the value of $HOST_BINDIR otherwise. 24653 + eval "HOST_BINDIR=\"$ocaml_bindir\"" 24654 + if test "x$bindir_to_libdir" = 'x' 24655 + then : 24656 + ocaml_bindir="$HOST_BINDIR" 24657 + else $as_nop 24658 + ocaml_bindir='' 24659 + fi 24378 24660 if test x"$TARGET_BINDIR" = 'x' 24379 24661 then : 24380 - TARGET_BINDIR="$ocaml_bindir" 24662 + if test "x$bindir_to_libdir" = 'x' 24663 + then : 24664 + TARGET_BINDIR="$HOST_BINDIR" 24665 + else $as_nop 24666 + TARGET_BINDIR='.' 24667 + fi 24668 + fi 24669 + eval "ocaml_libdir=\"$ocaml_libdir\"" 24670 + if test x"$TARGET_LIBDIR" = 'x' 24671 + then : 24672 + if test "x$bindir_to_libdir" = 'x' 24673 + then : 24674 + TARGET_LIBDIR="$ocaml_libdir" 24675 + else $as_nop 24676 + TARGET_LIBDIR="$bindir_to_libdir" 24677 + fi 24381 24678 fi 24382 24679 if test x"$target_launch_method" = 'x' 24383 24680 then : ··· 25341 25638 launch_method='$(echo "$launch_method" | sed -e "s/'/'\"'\"'/g")' 25342 25639 target_launch_method=\ 25343 25640 '$(echo "$target_launch_method" | sed -e "s/'/'\"'\"'/g")' 25344 - ocaml_bindir='$(echo "$ocaml_bindir" | sed -e "s/'/'\"'\"'/g")' 25641 + HOST_BINDIR='$(echo "$HOST_BINDIR" | sed -e "s/'/'\"'\"'/g")' 25345 25642 TARGET_BINDIR='$(echo "$TARGET_BINDIR" | sed -e "s/'/'\"'\"'/g")' 25346 25643 25347 25644 ocamltest_unix_mod='$ocamltest_unix_mod' ··· 26527 26824 chmod +x "$ofile" 26528 26825 26529 26826 ;; 26530 - "shebang":C) printf '%s\n%s\000\n' "$launch_method" "$ocaml_bindir" \ 26827 + "shebang":C) printf '%s\n%s\000\n' "$launch_method" "$HOST_BINDIR" \ 26531 26828 > stdlib/runtime.info 26532 26829 printf '%s\n%s\000\n' "$target_launch_method" "$TARGET_BINDIR" \ 26533 26830 > stdlib/target_runtime.info ;;
+196 -33
configure.ac
··· 84 84 unix_library="" 85 85 unix_directory="" 86 86 diff_supports_color=false 87 + target_libdir_is_relative=false 88 + srcdir_abs='' 89 + srcdir_abs_real='' 90 + build_map_flags='' 87 91 88 92 # Information about the package 89 93 ··· 216 220 AC_SUBST([unix_directory]) 217 221 AC_SUBST([cc_has_debug_prefix_map]) 218 222 AC_SUBST([as_has_debug_prefix_map]) 223 + AC_SUBST([as_is_cc]) 219 224 AC_SUBST([with_debugger]) # TODO: rename this variable 220 225 AC_SUBST([build_ocamldebug]) 221 226 AC_SUBST([build_ocamltex]) ··· 262 267 AC_SUBST([PACKLD]) 263 268 AC_SUBST([build_libraries_manpages]) 264 269 AC_SUBST([compute_deps]) 270 + AC_SUBST([ocaml_prefix]) 265 271 AC_SUBST([ocaml_bindir]) 266 272 AC_SUBST([ocaml_libdir]) 267 273 AC_SUBST([TARGET_LIBDIR]) 268 274 AC_SUBST([QS]) 269 275 AC_SUBST([ar_supports_response_files]) 276 + AC_SUBST([target_libdir_is_relative]) 277 + AC_SUBST([srcdir_abs]) 278 + AC_SUBST([srcdir_abs_real]) 279 + AC_SUBST([build_map_flags]) 270 280 271 281 ## Generated files 272 282 ··· 330 340 AS_IF([test -n "$target_alias"], 331 341 [ac_tool_prefix=$target_alias-]) 332 342 343 + # $cygwin_build_env=true if the build is taking place in any kind of Cygwin-like 344 + # environment (which may include cross-compiling _from_ Cygwin) 345 + # All patterns end with * (cf. build-aux/config.sub) 346 + # 347 + # In Cygwin itself, the mingw-w64 compilers are cross-compilers 348 + # (host=x86_64-pc-cygwin; target=*-w64-mingw32) and $build when running from 349 + # within Cygwin is always *-pc-cygwin. 350 + # 351 + # In MSYS2, the mingw-w64 compilers are normal host compilers, which MSYS2 makes 352 + # available through different Environments (similar to the Microsoft Visual 353 + # Studio Tools Command Prompts; see https://www.msys2.org/docs/environments/). 354 + # It is possible to use MSYS2's "Cygwin" gcc (the equivalent of compiling native 355 + # Cygwin), in which case $build is *-*-cygwin (some older MSYS2 installations 356 + # may report the legacy *-*-msys*) 357 + # The mingw-w64 Environments manually set $build to *-w64-mingw32, but the 358 + # _native_ value inferred by config.guess (which uses uname -s) will be 359 + # *-pc-mingw32 (for the 32-bit _target_ environments, even though MSYS2 is a 360 + # 64-bit build environment) and *-pc-mingw64 (for the 64-bit _target_ 361 + # environments). 362 + # 363 + # This leads to the four patterns below, all of which imply that the build is 364 + # taking place on a system where Cygwin's utilities (cygpath, etc.) can be 365 + # expected to be found and its semantics (CYGWIN=winsymlinks:native, etc.) be 366 + # expected to apply. 367 + # 368 + # Note that although build=x86_64-pc-mingw64 will be accepted here, it is highly 369 + # likely that that's a misconfigured environment, and the script will 370 + # subsequently fail if host has not been altered to x86_64-w64-mingw32. 371 + AS_CASE([$build], 372 + [*-*-cygwin*|*-*-msys*|*-*-mingw32*|*-*-mingw64*], 373 + [cygwin_build_env=true], 374 + [cygwin_build_env=false]) 375 + 333 376 # Ensure that AC_CONFIG_LINKS will either create symlinks which are compatible 334 377 # with native Windows (i.e. NTFS symlinks, not WSL or Cygwin-emulated ones) or 335 378 # use its fallback mechanisms. Native Windows versions of ocamlc/ocamlopt cannot 336 379 # interpret either WSL or Cygwin-emulated symlinks. 337 - AS_CASE([$host], 338 - [*-pc-windows|*-w64-mingw32*], 380 + AS_CASE([$cygwin_build_env,$host], 381 + [true,*-pc-windows|true,*-w64-mingw32*], 339 382 [AC_CONFIG_COMMANDS([native-symlinks], [], 340 383 [export CYGWIN="\$CYGWIN\${CYGWIN:+ }winsymlinks:nativestrict" 341 384 export MSYS="\$MSYS\${MSYS:+ }winsymlinks:nativestrict"])]) ··· 647 690 [AS_HELP_STRING([--enable-mmap-map-stack], 648 691 [use mmap to allocate stacks instead of malloc])]) 649 692 693 + AC_ARG_WITH([relative-libdir], 694 + [AS_HELP_STRING([--with-relative-libdir], 695 + m4_normalize([location of the Standard Library, specified relative to 696 + --bindir (if no argument is given to --with-relative-libdir, defaults to 697 + ../lib/ocaml)]))], 698 + [AS_CASE([$withval], 699 + [no], 700 + [bindir_to_libdir=''], 701 + [yes], 702 + [bindir_to_libdir="..${default_separator}lib${default_separator}ocaml"], 703 + [bindir_to_libdir="$withval"])], 704 + [bindir_to_libdir='']) 705 + 650 706 AC_ARG_WITH([afl], 651 707 [AS_HELP_STRING([--with-afl], 652 708 [use the AFL fuzzer])]) ··· 833 889 # See https://lists.gnu.org/archive/html/autoconf/2019-07/msg00002.html 834 890 # for the detailed explanation. 835 891 836 - ocamlsrcdir=$(unset CDPATH; cd -- "$srcdir" && printf %sX "$PWD") || fail 837 - ocamlsrcdir=${ocamlsrcdir%X} 892 + srcdir_abs=$(unset CDPATH; cd -- "$srcdir" && printf %sX "$PWD") || fail 893 + srcdir_abs=${srcdir_abs%X} 838 894 839 - AS_CASE([$host], 840 - [*-w64-mingw32*|*-pc-windows], 895 + AS_CASE([$cygwin_build_env,$host], 896 + [true,*-w64-mingw32*|true,*-pc-windows], 841 897 [OCAML_CHECK_LN_ON_WINDOWS 842 - ocamlsrcdir="$(LC_ALL=C.UTF-8 cygpath -w -- "$ocamlsrcdir")"], 843 - [ln='ln -sf']) 898 + ocamlsrcdir="$(LC_ALL=C.UTF-8 cygpath -w -- "$srcdir_abs")"], 899 + [ln='ln -sf' 900 + ocamlsrcdir="$srcdir_abs"]) 844 901 845 902 # Whether ar supports @FILE arguments 846 903 ··· 923 980 # in config.status, rather than by the .in mechanism, since the latter cannot 924 981 # reliably process binary files. 925 982 AC_CONFIG_COMMANDS([shebang], 926 - [printf '%s\n%s\000\n' "$launch_method" "$ocaml_bindir" \ 983 + [printf '%s\n%s\000\n' "$launch_method" "$HOST_BINDIR" \ 927 984 > stdlib/runtime.info 928 985 printf '%s\n%s\000\n' "$target_launch_method" "$TARGET_BINDIR" \ 929 986 > stdlib/target_runtime.info], ··· 934 991 [launch_method='$(echo "$launch_method" | sed -e "s/'/'\"'\"'/g")' 935 992 target_launch_method=\ 936 993 '$(echo "$target_launch_method" | sed -e "s/'/'\"'\"'/g")' 937 - ocaml_bindir='$(echo "$ocaml_bindir" | sed -e "s/'/'\"'\"'/g")' 994 + HOST_BINDIR='$(echo "$HOST_BINDIR" | sed -e "s/'/'\"'\"'/g")' 938 995 TARGET_BINDIR='$(echo "$TARGET_BINDIR" | sed -e "s/'/'\"'\"'/g")']) 939 996 940 997 # Checks for programs ··· 1158 1215 # ensure it can be executed from a native Windows process. The check 1159 1216 # is only necessary when cross-compiling. 1160 1217 AS_IF([test x"$build" != x"$host"],[ 1161 - AS_CASE([$build], 1162 - [*-pc-msys|*-*-cygwin], 1163 - [flexlink_where="$(cmd /c "$flexlink" -where 2>/dev/null)" 1164 - AS_IF([test -z "$flexlink_where"], 1165 - [AC_MSG_ERROR(m4_normalize([$flexlink is not executable from a 1166 - native Win32 process]))])]) 1218 + AS_IF([$cygwin_build_env], 1219 + [flexlink_where="$(cmd /c "$flexlink" -where 2>/dev/null)" 1220 + AS_IF([test -z "$flexlink_where"], 1221 + [AC_MSG_ERROR(m4_normalize([$flexlink is not executable from a 1222 + native Win32 process])) 1223 + ]) 1224 + ]) 1167 1225 ]) 1168 1226 ]) 1169 1227 ··· 1316 1374 1317 1375 # Checks for header files 1318 1376 1377 + AC_CHECK_HEADER([libgen.h],[AC_DEFINE([HAS_LIBGEN_H], [1])]) 1319 1378 AC_CHECK_HEADER([pthread_np.h],[AC_DEFINE([HAS_PTHREAD_NP_H], [1])]) 1320 1379 AC_CHECK_HEADER([dirent.h], [AC_DEFINE([HAS_DIRENT], [1])], [], 1321 1380 [#include <sys/types.h>]) ··· 1802 1861 # to avoiding forking a C compiler process for each compilation by ocamlopt. 1803 1862 # Both AS and ASPP can be overridden by the user. 1804 1863 1805 - default_as="$CC -c" 1806 - default_aspp="$CC -c" 1864 + as_is_cc=true 1865 + default_as='' 1807 1866 1808 1867 AS_CASE([$as_target,$ocaml_cc_vendor], 1809 1868 [*-*-linux*,gcc-*], 1810 1869 [AS_CASE([$as_cpu], 1811 1870 [x86_64|arm*|aarch64*|i[[3-6]]86|riscv*], 1812 - [default_as="${toolpref}as"])], 1871 + [default_as="${toolpref}as" 1872 + as_is_cc=false])], 1873 + [*-*-cygwin,gcc-*], 1874 + [default_as="${toolpref}as" 1875 + as_is_cc=false], 1813 1876 [i686-pc-windows,*], 1814 1877 [default_as="ml -nologo -coff -Cp -c -Fo" 1815 - default_aspp="$default_as"], 1878 + default_aspp="$default_as" 1879 + as_is_cc=false], 1816 1880 [x86_64-pc-windows,*], 1817 1881 [default_as="ml64 -nologo -Cp -c -Fo" 1818 - default_aspp="$default_as"], 1882 + default_aspp="$default_as" 1883 + as_is_cc=false], 1819 1884 [*-*-darwin*,clang-*], 1820 - [default_as="$default_as -Wno-trigraphs" 1885 + [default_as="$CC -c -Wno-trigraphs" 1821 1886 default_aspp="$default_as"]) 1887 + 1888 + AS_IF([test -z "$default_as"],[default_as="$CC -c"]) 1889 + AS_IF([test -z "$default_aspp"],[default_aspp="$CC -c"]) 1822 1890 1823 1891 AS_IF([test "$with_pic"], 1824 1892 [fpic=true ··· 2417 2485 2418 2486 ## -fdebug-prefix-map support by the C compiler 2419 2487 AS_CASE([$ocaml_cc_vendor,$target], 2420 - [*,*-w64-mingw32*], [cc_has_debug_prefix_map=false], 2421 2488 [*,*-pc-windows], [cc_has_debug_prefix_map=false], 2422 2489 [xlc*,powerpc-ibm-aix*], [cc_has_debug_prefix_map=false], 2423 2490 [sunc*,sparc-sun-*], [cc_has_debug_prefix_map=false], ··· 2425 2492 [cc_has_debug_prefix_map=true], [cc_has_debug_prefix_map=false], 2426 2493 [$warn_error_flag])]) 2427 2494 2495 + ## -ffile-prefix-map support by the C compiler - used in the build, not by 2496 + ## the compiler 2497 + AS_IF([test x"$bindir_to_libdir" != 'x'], 2498 + [srcdir_abs_real="$(realpath "$srcdir_abs" 2>/dev/null)" 2499 + AS_IF([test x"$srcdir_abs_real" = "x$srcdir_abs"], 2500 + [srcdir_abs_real='']) 2501 + AX_CHECK_COMPILE_FLAG([-Wa,--debug-prefix-map=old=new], 2502 + [build_map_flags='-Wa,--debug-prefix-map='], [], [$warn_error_flag]) 2503 + AX_CHECK_COMPILE_FLAG([-ffile-prefix-map=old=new], 2504 + [build_map_flags="$build_map_flags -ffile-prefix-map="], 2505 + [AS_IF([$cc_has_debug_prefix_map], 2506 + [build_map_flags="$build_map_flags -fdebug-prefix-map="])], 2507 + [$warn_error_flag])]) 2508 + 2428 2509 ## Does stat support nanosecond precision 2429 2510 2430 2511 stat_has_ns_precision=false ··· 2911 2992 AS_IF([test x"$libdir" = x'${exec_prefix}/lib'], 2912 2993 [libdir="$libdir"/ocaml]) 2913 2994 2914 - AS_IF([test x"$TARGET_LIBDIR" = x], 2915 - [TARGET_LIBDIR="$libdir"]) 2916 - 2917 2995 AS_IF([test x"$mandir" = x'${datarootdir}/man'], 2918 2996 [mandir='${prefix}/man']) 2919 2997 ··· 2923 3001 [i686-w64-mingw32*], [prefix='C:/ocamlmgw'], 2924 3002 [x86_64-w64-mingw32*], [prefix='C:/ocamlmgw64'], 2925 3003 [i686-pc-windows], [prefix='C:/ocamlms'], 2926 - [x86_64-pc-windows], [prefix='C:/ocamlms64'])], 2927 - [AS_CASE([$build,$host], 2928 - [*-*-cygwin,*-w64-mingw32*|*-*-cygwin,*-pc-windows], 2929 - [prefix="$(LC_ALL=C.UTF-8 cygpath -m "$prefix")"])]) 3004 + [x86_64-pc-windows], [prefix='C:/ocamlms64'])]) 3005 + 3006 + # Normalise $prefix, if necessary, on Windows. There are 9 variables to be 3007 + # considered: 3008 + # - $prefix and $exec_prefix. These are autoconf variables containing the values 3009 + # specified for --prefix and --exec-prefix respectively, or NONE if these 3010 + # flags were not given on the command line. These two variables are written to 3011 + # Makefile.config and are in _build_ format. On native Windows, the values 3012 + # must be suitable to pass to _both_ native Windows processes and Cygwin/MSYS2 3013 + # commands. The values are ultimately converted to Windows paths using slashes 3014 + # (i.e. C:/foo) 3015 + # - $bindir and $libdir. These similarly contain the values specified for 3016 + # --bindir and --libdir, or defaults relative to $exec_prefix otherwise. 3017 + # Unlike --prefix, values specified to configure for --bindir and --libdir are 3018 + # assumed to be suitable for both native Windows processes and Cygwin/MSYS2. 3019 + # These two variables ultimately end up in Makefile.config as $(BINDIR) and 3020 + # $(LIBDIR) and are used for installation commands only. 3021 + # - $ocaml_prefix, $ocaml_bindir and $ocaml_libdir are the _expanded_ values of 3022 + # $prefix, $bindir and $libdir so that the values can be inserted into OCaml 3023 + # strings (typically in utils/config.generated.ml). On Windows, these preserve 3024 + # the backslashes present in the value passed to --prefix. 3025 + # - $TARGET_BINDIR and $TARGET_LIBDIR. These are both precious environment 3026 + # variables (meaning their value is recorded by configure) but they default to 3027 + # $ocaml_bindir and $ocaml_libdir respectively. 3028 + ocaml_bindir="$bindir" 3029 + ocaml_libdir="$libdir" 3030 + ocaml_prefix="$prefix" 3031 + AS_CASE([$cygwin_build_env,$host], 3032 + [true,*-w64-mingw32*|true,*-pc-windows], 3033 + [prefix="$(LC_ALL=C.UTF-8 cygpath -m "$prefix")" 3034 + AS_IF([test "x${ocaml_prefix%%/*}" != "x$ocaml_prefix"], 3035 + # $prefix contained a slash - normalise it with cygpath. The rationale for 3036 + # this allows both `./configure --prefix $PWD/install` (which will be a 3037 + # Cygwin path) and also systems lazily using slashes instead of 3038 + # backslashes (i.e. C:/Backslashes/Scare/Us) to work. 3039 + [ocaml_prefix="$prefix"], 3040 + # $prefix was using backslashes - preserve these in the build, but 3041 + # continue to use slashes for the Makefile variables. 3042 + [AS_IF([test "x$bindir" = 'x${exec_prefix}/bin'], 3043 + [ocaml_bindir='${exec_prefix}\bin'], 3044 + [ocaml_bindir="$bindir"]) 3045 + AS_IF([test "x$libdir" = 'x${exec_prefix}/lib/ocaml'], 3046 + [ocaml_libdir='${exec_prefix}\lib\ocaml'], 3047 + [ocaml_libdir="$libdir"])])]) 3048 + 3049 + AS_IF([test x"$libdir" = x'${exec_prefix}/lib/ocaml'], 3050 + [AS_IF([test x"$bindir_to_libdir" != 'x'], 3051 + [ocaml_libdir="$bindir_to_libdir" 3052 + target_libdir_is_relative=true 3053 + AS_CASE([$cygwin_build_env,$host], 3054 + [true,*-w64-mingw32*|true,*-pc-windows], 3055 + [build_bindir_to_libdir="$(LC_ALL=C.UTF-8 cygpath \ 3056 + "$bindir_to_libdir")"], 3057 + [build_bindir_to_libdir="$bindir_to_libdir"]) 3058 + AS_CASE([$build_bindir_to_libdir], 3059 + [./*],[libdir="$bindir${build_bindir_to_libdir[#].}"], 3060 + [../*],[libdir="$bindir/$build_bindir_to_libdir"], 3061 + [AC_MSG_ERROR(m4_normalize([--with-relative-libdir requires an explicit 3062 + relative path]))])])], 3063 + [AS_IF([test x"$bindir_to_libdir" != 'x'], 3064 + [AC_MSG_ERROR(m4_normalize([--with-relative-libdir and --libdir cannot both 3065 + be specified]))])]) 3066 + 3067 + AS_IF([test x"$bindir_to_libdir" != 'x' && test x"$TARGET_LIBDIR" != 'x'], 3068 + [AC_MSG_ERROR(m4_normalize([--with-relative-libdir and TARGET_LIBDIR cannot 3069 + both be specified]))]) 2930 3070 2931 3071 # Define a few macros that were defined in config/m-nt.h 2932 3072 # but whose value is not guessed properly by configure ··· 2953 3093 AC_CONFIG_COMMANDS_PRE([ 2954 3094 saved_exec_prefix="$exec_prefix" 2955 3095 saved_prefix="$prefix" 3096 + prefix="$ocaml_prefix" 2956 3097 AS_IF([test "x$prefix" = "xNONE"],[prefix="$ac_default_prefix"]) 2957 3098 AS_IF([test "x$exec_prefix" = "xNONE"],[exec_prefix="$prefix"]) 2958 3099 eval "exec_prefix=\"$exec_prefix\"" 2959 - eval "ocaml_bindir=\"$bindir\"" 2960 - eval "ocaml_libdir=\"$libdir\"" 2961 - AS_IF([test x"$TARGET_BINDIR" = 'x'],[TARGET_BINDIR="$ocaml_bindir"]) 3100 + # Set variables necessary to create utils/config.generated.ml and the two 3101 + # runtime-launch-info templates in stdlib. 3102 + # $ocaml_bindir is used for utils/config.generated.ml and is _empty_ if the 3103 + # compiler is configured with --with-relative-libdir (otherwise the path 3104 + # would be embedded in config.cmo) 3105 + # $HOST_BINDIR and $TARGET_BINDIR are used to generate the two 3106 + # runtime-launch-info files. $HOST_BINDIR is always the absolute path to the 3107 + # binary directory, in host format (i.e. potentially with backslashes on 3108 + # Windows). $TARGET_BINDIR can be specified by the caller when building 3109 + # cross-compilers, and the value then is used unaltered. Otherwise, 3110 + # $TARGET_BINDIR is set to '.' when the compiler is configured with 3111 + # --with-relative-libdir or the value of $HOST_BINDIR otherwise. 3112 + eval "HOST_BINDIR=\"$ocaml_bindir\"" 3113 + AS_IF([test "x$bindir_to_libdir" = 'x'], 3114 + [ocaml_bindir="$HOST_BINDIR"], 3115 + [ocaml_bindir='']) 3116 + AS_IF([test x"$TARGET_BINDIR" = 'x'], 3117 + [AS_IF([test "x$bindir_to_libdir" = 'x'], 3118 + [TARGET_BINDIR="$HOST_BINDIR"], 3119 + [TARGET_BINDIR='.'])]) 3120 + eval "ocaml_libdir=\"$ocaml_libdir\"" 3121 + AS_IF([test x"$TARGET_LIBDIR" = 'x'], 3122 + [AS_IF([test "x$bindir_to_libdir" = 'x'], 3123 + [TARGET_LIBDIR="$ocaml_libdir"], 3124 + [TARGET_LIBDIR="$bindir_to_libdir"])]) 2962 3125 AS_IF([test x"$target_launch_method" = 'x'], 2963 3126 [target_launch_method="$launch_method"]) 2964 3127 prefix="$saved_prefix"
+13
driver/compenv.ml
··· 43 43 prerr_endline err; 44 44 raise (Exit_with_status 2) 45 45 46 + let fatalf fmt = Printf.ksprintf fatal fmt 47 + 46 48 let extract_output = function 47 49 | Some s -> s 48 50 | None -> ··· 778 780 Printf.sprintf "Usage: %s <options> <files>\nOptions are:" program in 779 781 Printf.printf "%s\n%s" help_msg err_msg; 780 782 raise (Exit_with_status 0) 783 + 784 + let parse_runtime_parameter opt = 785 + let k, setting = 786 + try Misc.cut_at opt '=' 787 + with Not_found -> 788 + fatalf "-set-runtime-default: invalid runtime parameter '%s'. \ 789 + Expected <name>=<value>." opt in 790 + if k = "standard_library_default" then 791 + Clflags.standard_library_default := Some setting 792 + else 793 + fatalf "-set-runtime-default: unrecognized runtime parameter %s." k
+4
driver/compenv.mli
··· 23 23 val print_version_string : unit -> 'a 24 24 val print_standard_library : unit -> 'a 25 25 val fatal : string -> 'a 26 + val fatalf : ('a, unit, string, 'b) format4 -> 'a 26 27 27 28 val first_ccopts : string list ref 28 29 val first_ppx : string list ref ··· 79 80 *) 80 81 val parse_arguments : ?current:(int ref) 81 82 -> string array ref -> Arg.anon_fun -> string -> unit 83 + 84 + (** Validate a single -set-runtime-default parameter specification. *) 85 + val parse_runtime_parameter : string -> unit
+8
driver/main_args.ml
··· 163 163 "<dir> Add <dir> to the list of \"hidden\" include directories\n\ 164 164 \ (Like -I, but the program can not directly reference these dependencies)" 165 165 166 + let mk_set_runtime_default f = 167 + "-set-runtime-default", Arg.String f, "<param>=<value> Set the default for \ 168 + runtime parameter <param> to <value> (see the manual for further details)" 169 + 166 170 let mk_impl f = 167 171 "-impl", Arg.String f, "<file> Compile <file> as a .ml file" 168 172 ··· 893 897 val _runtime_variant : string -> unit 894 898 val _with_runtime : unit -> unit 895 899 val _without_runtime : unit -> unit 900 + val _set_runtime_default : string -> unit 896 901 val _short_paths : unit -> unit 897 902 val _thread : unit -> unit 898 903 val _v : unit -> unit ··· 1121 1126 mk_without_runtime F._without_runtime; 1122 1127 mk_safe_string; 1123 1128 mk_safer_matching F._safer_matching; 1129 + mk_set_runtime_default F._set_runtime_default; 1124 1130 mk_short_paths F._short_paths; 1125 1131 mk_strict_sequence F._strict_sequence; 1126 1132 mk_no_strict_sequence F._no_strict_sequence; ··· 1346 1352 mk_S F._S; 1347 1353 mk_safe_string; 1348 1354 mk_safer_matching F._safer_matching; 1355 + mk_set_runtime_default F._set_runtime_default; 1349 1356 mk_shared F._shared; 1350 1357 mk_short_paths F._short_paths; 1351 1358 mk_strict_sequence F._strict_sequence; ··· 1839 1846 let _plugin _p = plugin := true 1840 1847 let _pp s = preprocessor := (Some s) 1841 1848 let _runtime_variant s = runtime_variant := s 1849 + let _set_runtime_default s = Compenv.parse_runtime_parameter s 1842 1850 let _stop_after pass = 1843 1851 let module P = Compiler_pass in 1844 1852 match P.of_string pass with
+1
driver/main_args.mli
··· 119 119 val _runtime_variant : string -> unit 120 120 val _with_runtime : unit -> unit 121 121 val _without_runtime : unit -> unit 122 + val _set_runtime_default : string -> unit 122 123 val _short_paths : unit -> unit 123 124 val _thread : unit -> unit 124 125 val _v : unit -> unit
+1 -1
driver/maindriver.ml
··· 62 62 "Please specify at most one of -pack, -a, -c, -output-obj"; 63 63 | Some ((P.Parsing | P.Typing | P.Lambda) as p) -> 64 64 assert (P.is_compilation_pass p); 65 - Printf.ksprintf Compenv.fatal 65 + Compenv.fatalf 66 66 "Options -i and -stop-after (%s) \ 67 67 are incompatible with -pack, -a, -output-obj" 68 68 (String.concat "|"
+1 -1
driver/optmaindriver.ml
··· 78 78 -output-obj"; 79 79 | Some ((P.Parsing | P.Typing | P.Lambda | P.Scheduling | P.Emit) as p) -> 80 80 assert (P.is_compilation_pass p); 81 - Printf.ksprintf Compenv.fatal 81 + Compenv.fatalf 82 82 "Options -i and -stop-after (%s) \ 83 83 are incompatible with -pack, -a, -shared, -output-obj" 84 84 (String.concat "|"
+2 -1
file_formats/cmx_format.mli
··· 46 46 mutable ui_send_fun: int list; (* Send functions needed *) 47 47 mutable ui_export_info: export_info; 48 48 mutable ui_force_link: bool; (* Always linked *) 49 - mutable ui_for_pack: string option } (* Part of a pack *) 49 + mutable ui_for_pack: string option; (* Part of a pack *) 50 + mutable ui_need_stdlib: bool} (* caml_standard_library_nat needed *) 50 51 51 52 (* Each .a library has a matching .cmxa file that provides the following 52 53 infos on the library: *)
+1
lambda/lambda.ml
··· 25 25 | Ostype_win32 26 26 | Ostype_cygwin 27 27 | Backend_type 28 + | Standard_library_default 28 29 29 30 type immediate_or_pointer = 30 31 | Immediate
+1
lambda/lambda.mli
··· 26 26 | Ostype_win32 27 27 | Ostype_cygwin 28 28 | Backend_type 29 + | Standard_library_default 29 30 30 31 type immediate_or_pointer = 31 32 | Immediate
+2 -1
lambda/printlambda.ml
··· 269 269 | Ostype_unix -> "ostype_unix" 270 270 | Ostype_win32 -> "ostype_win32" 271 271 | Ostype_cygwin -> "ostype_cygwin" 272 - | Backend_type -> "backend_type" in 272 + | Backend_type -> "backend_type" 273 + | Standard_library_default -> "standard_library_default" in 273 274 fprintf ppf "sys.constant_%s" const_name 274 275 | Pisint -> fprintf ppf "isint" 275 276 | Pisout -> fprintf ppf "isout"
+2
lambda/translprim.ml
··· 167 167 "%ostype_unix", Primitive ((Pctconst Ostype_unix), 1); 168 168 "%ostype_win32", Primitive ((Pctconst Ostype_win32), 1); 169 169 "%ostype_cygwin", Primitive ((Pctconst Ostype_cygwin), 1); 170 + "%standard_library_default", 171 + Primitive ((Pctconst Standard_library_default), 1); 170 172 "%frame_pointers", Frame_pointers; 171 173 "%negint", Primitive (Pnegint, 1); 172 174 "%succint", Primitive ((Poffsetint 1), 1);
+9
man/ocamlc.1
··· 674 674 wrongly assumed to be exhaustive. This only impacts GADT and 675 675 polymorphic variant compilation. 676 676 .TP 677 + .BI \-set\-runtime\-default " setting=value" 678 + When linking an executable, override the default value for a runtime setting. 679 + The only currently supported setting is: 680 + 681 + .B standard_library_default 682 + Specifies the default location used by the executable to locate the Standard 683 + Library. By default, this is the absolute path to the Standard Library the 684 + compiler itself was configured with. 685 + .TP 677 686 .B \-short\-paths 678 687 When a type is visible under several module-paths, use the shortest 679 688 one when printing the type's name in inferred interfaces and error and
+9
man/ocamlopt.1
··· 593 593 supported passes are: 594 594 .BR scheduling . 595 595 .TP 596 + .BI \-set\-runtime\-default " setting=value" 597 + When linking an executable, override the default value for a runtime setting. 598 + The only currently supported setting is: 599 + 600 + .B standard_library_default 601 + Specifies the default location used by the executable to locate the Standard 602 + Library. By default, this is the absolute path to the Standard Library the 603 + compiler itself was configured with. 604 + .TP 596 605 .B \-shared 597 606 Build a plugin (usually .cmxs) that can be dynamically loaded with 598 607 the
+11
manual/src/cmds/unified-options.etex
··· 711 711 ). 712 712 }%nat 713 713 714 + \notop{% 715 + \item["-set-runtime-default" \var{name=value}] 716 + When linking an executable, override the default value for a runtime setting. 717 + The currently supported settings are: 718 + \begin{description} 719 + \item["standard_library_default"] Specifies the default location used by the 720 + executable to locate the Standard Library. By default, this is the absolute 721 + path to the Standard Library the compiler itself was configured with. 722 + \end{description} 723 + }%notop 724 + 714 725 \nat{% 715 726 \item["-shared"] 716 727 Build a plugin (usually ".cmxs") that can be dynamically loaded with
+25 -16
middle_end/closure/closure.ml
··· 1056 1056 None ubody), 1057 1057 approx) 1058 1058 (* Compile-time constants *) 1059 - | Lprim(Pctconst c, [arg], _loc) -> 1060 - let cst, approx = 1061 - match c with 1062 - | Big_endian -> make_const_bool B.big_endian 1063 - | Word_size -> make_const_int (8*B.size_int) 1064 - | Int_size -> make_const_int (8*B.size_int - 1) 1065 - | Max_wosize -> make_const_int ((1 lsl ((8*B.size_int) - 10)) - 1 ) 1066 - | Ostype_unix -> make_const_bool (Config.target_os_type = "Unix") 1067 - | Ostype_win32 -> make_const_bool (Config.target_os_type = "Win32") 1068 - | Ostype_cygwin -> make_const_bool (Config.target_os_type = "Cygwin") 1069 - | Backend_type -> 1070 - make_const_int 0 (* tag 0 is the same as Native here *) 1059 + | Lprim(Pctconst c, [arg], loc) -> 1060 + let cst f v = 1061 + let cst, approx = f v in 1062 + let arg, _approx = close env arg in 1063 + let id = Ident.create_local "dummy" in 1064 + Ulet(Immutable, Pgenval, VP.create id, arg, cst), approx 1071 1065 in 1072 - let arg, _approx = close env arg in 1073 - let id = Ident.create_local "dummy" in 1074 - Ulet(Immutable, Pgenval, VP.create id, arg, cst), approx 1066 + begin match c with 1067 + | Big_endian -> cst make_const_bool B.big_endian 1068 + | Word_size -> cst make_const_int (8*B.size_int) 1069 + | Int_size -> cst make_const_int (8*B.size_int - 1) 1070 + | Max_wosize -> cst make_const_int ((1 lsl ((8*B.size_int) - 10)) - 1) 1071 + | Ostype_unix -> cst make_const_bool (Config.target_os_type = "Unix") 1072 + | Ostype_win32 -> cst make_const_bool (Config.target_os_type = "Win32") 1073 + | Ostype_cygwin -> cst make_const_bool (Config.target_os_type = "Cygwin") 1074 + | Backend_type -> 1075 + cst make_const_int 0 (* tag 0 is the same as Native here *) 1076 + | Standard_library_default -> 1077 + Compilenv.need_stdlib_location (); 1078 + let dbg = Debuginfo.from_location loc in 1079 + let id = Ident.name Compilenv.stdlib_symbol_name in 1080 + Uprim(P.Pread_symbol id, [], dbg), Value_const (Uconst_ref (id, None)) 1081 + end 1075 1082 | Lprim(Pignore, [arg], _loc) -> 1076 1083 let expr, approx = make_const_int 0 in 1077 1084 Usequence(fst (close env arg), expr), approx ··· 1463 1470 | Uconst_ref (s, (Some c)) -> 1464 1471 Compilenv.add_exported_constant s; 1465 1472 structured_constant c 1466 - | Uconst_ref (_s, None) -> assert false (* Cannot be generated *) 1473 + | Uconst_ref (s, None) -> 1474 + (* Only generated in one context *) 1475 + assert (s = Ident.name Compilenv.stdlib_symbol_name) 1467 1476 | Uconst_int _ -> () 1468 1477 and structured_constant = function 1469 1478 | Uconst_block (_, ul) -> List.iter const ul
+14 -2
middle_end/compilenv.ml
··· 88 88 ui_send_fun = []; 89 89 ui_force_link = false; 90 90 ui_export_info = default_ui_export_info; 91 - ui_for_pack = None } 91 + ui_for_pack = None; 92 + ui_need_stdlib = false } 92 93 93 94 let linuxlike_mangling = match Config.system with 94 95 | "macosx" ··· 131 132 current_unit.ui_send_fun <- []; 132 133 current_unit.ui_force_link <- !Clflags.link_everything; 133 134 current_unit.ui_for_pack <- packname; 135 + current_unit.ui_need_stdlib <- false; 134 136 Hashtbl.clear exported_constants; 135 137 structured_constants := structured_constants_empty; 136 138 current_unit.ui_export_info <- default_ui_export_info; ··· 261 263 | None -> Clambda.Value_unknown 262 264 | Some ui -> get_clambda_approx ui 263 265 266 + (* The name of the symbol defined globally for %standard_library_default *) 267 + let stdlib_symbol_name = Ident.create_persistent "caml_standard_library_nat" 268 + 264 269 (* Return the symbol used to refer to a global identifier *) 265 270 266 271 let symbol_for_global id = 267 272 if Ident.is_predef id then 268 273 "caml_exn_" ^ Ident.name id 274 + else if Ident.same stdlib_symbol_name id then 275 + Ident.name id 269 276 else begin 270 277 let unitname = Ident.name id in 271 278 match ··· 293 300 294 301 let symbol_for_global' id = 295 302 let sym_label = Linkage_name.create (symbol_for_global id) in 296 - if Ident.is_predef id then 303 + if Ident.is_predef id || Ident.same stdlib_symbol_name id then 297 304 Symbol.of_global_linkage predefined_exception_compilation_unit sym_label 298 305 else 299 306 Symbol.of_global_linkage (unit_for_global id) sym_label ··· 350 357 let need_send_fun n = 351 358 if not (List.mem n current_unit.ui_send_fun) then 352 359 current_unit.ui_send_fun <- n :: current_unit.ui_send_fun 360 + 361 + (* Record that caml_standard_library_nat is needed *) 362 + 363 + let need_stdlib_location () = 364 + current_unit.ui_need_stdlib <- true 353 365 354 366 (* Write the description of the current unit *) 355 367
+8
middle_end/compilenv.mli
··· 108 108 (* Record the need of a currying (resp. application, 109 109 message sending) function with the given arity *) 110 110 111 + val need_stdlib_location: unit -> unit 112 + (* Record that caml_standard_library_nat needs to be initialised if this 113 + unit is linked. *) 114 + 115 + val stdlib_symbol_name: Ident.t 116 + (* The name of the symbol defined globally for 117 + %standard_library_default *) 118 + 111 119 val new_const_symbol : unit -> string 112 120 val closure_symbol : Closure_id.t -> Symbol.t 113 121 (* Symbol of a function if the function is
+23 -19
middle_end/flambda/closure_conversion.ml
··· 384 384 ~name:Names.raise) 385 385 | Lprim (Pctconst c, [arg], _loc) -> 386 386 let module Backend = (val t.backend) in 387 - let const = 388 - begin match c with 389 - | Big_endian -> lambda_const_bool Backend.big_endian 390 - | Word_size -> lambda_const_int (8*Backend.size_int) 391 - | Int_size -> lambda_const_int (8*Backend.size_int - 1) 392 - | Max_wosize -> 393 - lambda_const_int ((1 lsl ((8*Backend.size_int) - 10)) - 1) 394 - | Ostype_unix -> 395 - lambda_const_bool (String.equal Config.target_os_type "Unix") 396 - | Ostype_win32 -> 397 - lambda_const_bool (String.equal Config.target_os_type "Win32") 398 - | Ostype_cygwin -> 399 - lambda_const_bool (String.equal Config.target_os_type "Cygwin") 400 - | Backend_type -> 401 - Lambda.const_int 0 (* tag 0 is the same as Native *) 402 - end 403 - in 404 - close t env 405 - (Lambda.Llet(Strict, Pgenval, Ident.create_local "dummy", 387 + let cst f v = 388 + let const = f v in 389 + close t env (Lambda.Llet(Strict, Pgenval, Ident.create_local "dummy", 406 390 arg, Lconst const)) 391 + in 392 + begin match c with 393 + | Big_endian -> cst lambda_const_bool Backend.big_endian 394 + | Word_size -> cst lambda_const_int (8*Backend.size_int) 395 + | Int_size -> cst lambda_const_int (8*Backend.size_int - 1) 396 + | Max_wosize -> 397 + cst lambda_const_int ((1 lsl ((8*Backend.size_int) - 10)) - 1) 398 + | Ostype_unix -> 399 + cst lambda_const_bool (String.equal Config.target_os_type "Unix") 400 + | Ostype_win32 -> 401 + cst lambda_const_bool (String.equal Config.target_os_type "Win32") 402 + | Ostype_cygwin -> 403 + cst lambda_const_bool (String.equal Config.target_os_type "Cygwin") 404 + | Backend_type -> cst Lambda.const_int 0 (* tag 0 is the same as Native *) 405 + | Standard_library_default -> 406 + Compilenv.need_stdlib_location (); 407 + let symbol = t.symbol_for_global' Compilenv.stdlib_symbol_name in 408 + t.imported_symbols <- Symbol.Set.add symbol t.imported_symbols; 409 + name_expr (Symbol symbol) ~name:Names.pgetglobal 410 + end 407 411 | Lprim (Pfield _, [Lprim (Pgetglobal id, [],_)], _) 408 412 when Ident.same id t.current_unit_id -> 409 413 Misc.fatal_errorf "[Pfield (Pgetglobal ...)] for the current compilation \
+10 -1
ocamltest/ocaml_tests.ml
··· 46 46 check_program_output; 47 47 ] @ 48 48 (if not Sys.win32 && Ocamltest_config.native_compiler then 49 - opt_build @ [compare_bytecode_programs] 49 + (* If the compiler is configured using --with-relative-libdir then at 50 + present we can't compare the bytecode programs because ocamlc.opt and 51 + ocamlrun are at different levels in the build tree, but they're both 52 + configured with the same relative directory path. 53 + This problem will disappear when ocamltest runs the testsuite against a 54 + compiler in an install-tree like way. *) 55 + if Ocamltest_config.has_relative_libdir then 56 + opt_build 57 + else 58 + opt_build @ [compare_bytecode_programs] 50 59 else 51 60 [] 52 61 )
+2
ocamltest/ocamltest_config.ml.in
··· 102 102 let frame_pointers = @frame_pointers@ 103 103 104 104 let tsan = @tsan@ 105 + 106 + let has_relative_libdir = @target_libdir_is_relative@
+3
ocamltest/ocamltest_config.mli
··· 145 145 146 146 val tsan : bool 147 147 (** Whether ThreadSanitizer support has been enabled at configure time *) 148 + 149 + val has_relative_libdir : bool 150 + (** Whether the compiler has been configured using --with-relative-libdir *)
+2 -2
runtime/backtrace_byt.c
··· 451 451 CAMLassert(di->already_read == 0); 452 452 di->already_read = 1; 453 453 454 - /* At the moment, bytecode programs built with --output-complete-exe 454 + /* At the moment, bytecode programs built with -output-complete-exe 455 455 do not contain any debug info. 456 456 457 457 See https://github.com/ocaml/ocaml/issues/9344 for details. 458 458 */ 459 - if (caml_params->cds_file == NULL && caml_byte_program_mode == COMPLETE_EXE) 459 + if (caml_params->cds_file == NULL && caml_byte_program_mode == EMBEDDED) 460 460 CAMLreturn0; 461 461 462 462 if (caml_params->cds_file != NULL) {
+28
runtime/caml/osdeps.h
··· 96 96 void caml_plat_mem_decommit(void *, uintnat); 97 97 void caml_plat_mem_unmap(void *, uintnat); 98 98 99 + /* caml_locate_standard_library(exe_name, stdlib_default, dirname) returns the 100 + location of the Standard Library. The location returned is absolute, if 101 + stdlib_default is a relative path then the result is computed relative to the 102 + directory portion of exe_name. 103 + 104 + If dirname is not NULL and stdlib_default is a relative path, a copy of the 105 + directory name part of exe_name is returned in dirname. If stdlib_default is 106 + an absolute path, dirname is never changed. 107 + 108 + Both strings are allocated with [caml_stat_alloc], so should be freed using 109 + [caml_stat_free]. 110 + */ 111 + CAMLextern char_os *caml_locate_standard_library (const char_os *exe_name, 112 + const char_os *stdlib_default, 113 + char_os **dirname); 114 + 99 115 #ifdef _WIN32 100 116 101 117 #include <time.h> ··· 158 174 CAMLextern uint64_t caml_time_counter(void); 159 175 160 176 extern void caml_init_os_params(void); 177 + 178 + /* True if: 179 + - dir equals "." 180 + - dir equals ".." 181 + - dir begins "./" 182 + - dir begins "../" 183 + The tests for null avoid the need to call strlen_os. */ 184 + #define Is_relative_dir(dir) \ 185 + (dir[0] == '.' \ 186 + && (dir[1] == '\0' \ 187 + || Is_separator(dir[1]) \ 188 + || (dir[1] == '.' && (dir[2] == '\0' || Is_separator(dir[2]))))) 161 189 162 190 #endif /* CAML_INTERNALS */ 163 191
+4
runtime/caml/s.h.in
··· 116 116 117 117 #undef HAS_DECL_SETTHREADDESCRIPTION 118 118 119 + #undef HAS_LIBGEN_H 120 + 121 + /* Define HAS_LIBGEN_H if you have /usr/include/libgen.h. */ 122 + 119 123 #undef HAS_DIRENT 120 124 121 125 /* Define HAS_DIRENT if you have /usr/include/dirent.h and the result of
+11 -6
runtime/caml/startup.h
··· 48 48 extern int32_t caml_seek_section(int fd, struct exec_trailer *trail, 49 49 const char *name); 50 50 51 - enum caml_byte_program_mode 52 - { 53 - STANDARD /* normal bytecode program requiring "ocamlrun" */, 54 - COMPLETE_EXE /* embedding the vm, i.e. compiled with --output-complete-exe */ 55 - }; 51 + enum caml_byte_program_mode { 52 + STANDARD, /* Default mode for ocamlrun */ 53 + APPENDED, /* bytecode must be appended (i.e. -custom) */ 54 + EMBEDDED /* bytecode embedded in C (e.g. -output-complete-exe/-output-obj) */ 55 + }; 56 + 57 + extern const enum caml_byte_program_mode caml_byte_program_mode; 56 58 57 - extern enum caml_byte_program_mode caml_byte_program_mode; 59 + /* The default location of the Standard Library as used by the runtime to find 60 + ld.conf */ 61 + extern const char_os *caml_runtime_standard_library_default; 62 + extern const char_os *caml_runtime_standard_library_effective; 58 63 59 64 #endif /* CAML_INTERNALS */ 60 65
+4
runtime/caml/sys.h
··· 35 35 36 36 CAMLnoret CAMLextern void caml_do_exit (int); 37 37 38 + /* The default location of the Standard Library as used by the 39 + %standard_library_default primitive */ 40 + extern char_os *caml_standard_library_default; 41 + 38 42 #endif /* CAML_INTERNALS */ 39 43 40 44 #endif /* CAML_SYS_H */
+2 -1
runtime/dynlink.c
··· 278 278 if (lib_path != NULL) 279 279 for (char_os *p = lib_path; *p != 0; p += strlen_os(p) + 1) 280 280 caml_ext_table_add(&caml_shared_libs_path, p); 281 - caml_parse_ld_conf(OCAML_STDLIB_DIR, &caml_shared_libs_path); 281 + caml_parse_ld_conf(caml_runtime_standard_library_effective, 282 + &caml_shared_libs_path); 282 283 /* Open the shared libraries */ 283 284 caml_ext_table_init(&shared_libs, 8); 284 285 if (libs != NULL)
+11
runtime/gen_primsc.sh
··· 31 31 #define CAML_INTERNALS 32 32 #include "caml/mlvalues.h" 33 33 #include "caml/prims.h" 34 + #include "caml/startup.h" 35 + #include "build_config.h" 34 36 35 37 EOF 36 38 ··· 61 63 echo 'const char * const caml_names_of_builtin_cprim[] = {' 62 64 sed -e 's/.*/ "&",/' "$primitives" 63 65 echo ' 0 };' 66 + 67 + # ocamlrun values for symbols which are provided by the bytecode linker 68 + # - ocamlrun is able to use any of the mechanisms to load the bytecode 69 + # - caml_runtime_standard_library_default for bytecode images on this runtime 70 + cat <<'EOF' 71 + 72 + const enum caml_byte_program_mode caml_byte_program_mode = STANDARD; 73 + const char_os *caml_runtime_standard_library_default = OCAML_STDLIB_DIR; 74 + EOF
+59 -14
runtime/startup_byt.c
··· 72 72 #define SEEK_END 2 73 73 #endif 74 74 75 + const char_os * caml_runtime_standard_library_effective = NULL; 76 + 75 77 static char magicstr[EXEC_MAGIC_LENGTH+1]; 76 78 77 79 /* Print the specified error message followed by an end-of-line and exit */ ··· 112 114 (strncmp(trail->magic, EXEC_MAGIC, sizeof(trail->magic)) == 0) 113 115 ? 0 : WRONG_MAGIC; 114 116 } 115 - 116 - enum caml_byte_program_mode caml_byte_program_mode = STANDARD; 117 117 118 118 int caml_attempt_open(char_os **name, struct exec_trailer *trail, 119 119 int do_open_script) ··· 381 381 const char_os * stdlib; 382 382 stdlib = caml_secure_getenv(T("OCAMLLIB")); 383 383 if (stdlib == NULL) stdlib = caml_secure_getenv(T("CAMLLIB")); 384 - if (stdlib == NULL) stdlib = OCAML_STDLIB_DIR; 384 + if (stdlib == NULL) stdlib = caml_runtime_standard_library_effective; 385 385 return stdlib; 386 386 } 387 387 ··· 394 394 /* Print the runtime configuration */ 395 395 printf("version: %s\n", OCAML_VERSION_STRING); 396 396 printf("standard_library_default: %s\n", 397 - caml_stat_strdup_of_os(OCAML_STDLIB_DIR)); 397 + caml_stat_strdup_of_os(caml_runtime_standard_library_default)); 398 398 printf("standard_library: %s\n", 399 399 caml_stat_strdup_of_os(get_stdlib_location())); 400 400 printf("int_size: %d\n", 8 * (int)sizeof(value)); ··· 433 433 puts("shared_libs_path:"); 434 434 caml_decompose_path(&caml_shared_libs_path, 435 435 caml_secure_getenv(T("CAML_LD_LIBRARY_PATH"))); 436 - caml_parse_ld_conf(OCAML_STDLIB_DIR, &caml_shared_libs_path); 436 + caml_parse_ld_conf(caml_runtime_standard_library_effective, 437 + &caml_shared_libs_path); 437 438 for (int i = 0; i < caml_shared_libs_path.size; i++) { 438 439 dir = caml_shared_libs_path.contents[i]; 439 440 if (dir[0] == 0) ··· 462 463 463 464 CAMLexport void caml_main(char_os **argv) 464 465 { 465 - int fd, pos; 466 + int fd = -1, pos; 466 467 struct exec_trailer trail; 467 468 struct channel * chan; 468 469 value res; 469 470 char * req_prims; 470 471 char_os * shared_lib_path, * shared_libs; 471 - char_os * exe_name, * proc_self_exe; 472 + char_os * exe_name, * proc_self_exe, * argv0; 472 473 473 474 /* Determine options */ 474 475 caml_parse_ocamlrunparam(); ··· 489 490 /* Determine position of bytecode file */ 490 491 pos = 0; 491 492 492 - /* First, try argv[0] (when ocamlrun is called by a bytecode program) */ 493 - exe_name = argv[0]; 494 - fd = caml_attempt_open(&exe_name, &trail, 0); 493 + argv0 = proc_self_exe = caml_executable_name(); 495 494 496 - proc_self_exe = caml_executable_name(); 495 + /* In APPENDED mode (i.e. with -custom), we always want to load the bytecode 496 + from the running executable, and argv[0] should never be used. However, 497 + some platforms still don't implement caml_executable_name, so there is an 498 + escape hatch here to fallback to checking argv[0] if proc_self_exe is 499 + NULL. 500 + For STANDARD mode (i.e. the current executable is ocamlrun), argv[0] is 501 + tried first, as this should be the path to shebang-script/executable 502 + originally executed by the user. */ 503 + CAMLassert(caml_byte_program_mode != EMBEDDED); 504 + if (caml_byte_program_mode != APPENDED || proc_self_exe == NULL) { 505 + exe_name = argv[0]; 506 + fd = caml_attempt_open(&exe_name, &trail, 0); 507 + } 497 508 498 509 /* Little grasshopper wonders why we do that at all, since 499 510 "The current executable is ocamlrun itself, it's never a bytecode ··· 501 512 With -custom, we have an executable that is ocamlrun itself 502 513 concatenated with the bytecode. So, if the attempt with argv[0] 503 514 failed, it is worth trying again with executable_name. */ 504 - if (fd < 0 && proc_self_exe != NULL) { 505 - exe_name = proc_self_exe; 506 - fd = caml_attempt_open(&exe_name, &trail, 0); 515 + if (caml_byte_program_mode == APPENDED || fd < 0) { 516 + if (proc_self_exe != NULL) { 517 + exe_name = proc_self_exe; 518 + fd = caml_attempt_open(&exe_name, &trail, 0); 519 + } 520 + if (fd < 0 && caml_byte_program_mode == APPENDED) 521 + error("unable to open file '%s'", caml_stat_strdup_of_os(exe_name)); 507 522 } 508 523 524 + if (argv0 == NULL) 525 + argv0 = caml_search_exe_in_path(exe_name); 526 + 509 527 if (fd < 0) { 510 528 pos = parse_command_line(argv); 511 529 if (caml_params->print_config) { 530 + caml_runtime_standard_library_effective = 531 + caml_locate_standard_library(argv0, 532 + caml_runtime_standard_library_default, 533 + NULL); 534 + 512 535 do_print_config(); 513 536 exit(0); 514 537 } ··· 539 562 } 540 563 /* Read the table of contents (section descriptors) */ 541 564 caml_read_section_descriptors(fd, &trail); 565 + 566 + caml_runtime_standard_library_effective = 567 + caml_locate_standard_library(argv0, 568 + caml_runtime_standard_library_default, NULL); 569 + if (argv0 != proc_self_exe) 570 + caml_stat_free(argv0); 571 + 572 + /* Load the embedded overridden caml_standard_library_default value, if one is 573 + available. Note that although -custom executables come through this 574 + mechanism, they don't define OSLD sections because 575 + caml_runtime_standard_library_default and caml_standard_library_default are 576 + fundamentally equal and caml_runtime_standard_library_default is set when 577 + the -custom executable is linked. */ 578 + char_os *image_standard_library_default = 579 + read_section_to_os(fd, &trail, "OSLD"); 580 + if (image_standard_library_default != NULL) 581 + caml_standard_library_default = image_standard_library_default; 582 + 542 583 /* Initialize the abstract machine */ 543 584 caml_init_gc (); 544 585 ··· 639 680 exe_name = caml_search_exe_in_path(argv[0]); 640 681 else 641 682 exe_name = proc_self_exe; 683 + 684 + caml_runtime_standard_library_effective = 685 + caml_locate_standard_library(exe_name, 686 + caml_runtime_standard_library_default, NULL); 642 687 643 688 Caml_state->external_raise = NULL; 644 689 /* Setup signal handling */
+41
runtime/sys.c
··· 736 736 { 737 737 return Val_int(1); /* Bytecode backed */ 738 738 } 739 + 740 + /* The native code linker doesn't synthesise calls to this primitive, instead 741 + putting the required string statically in caml_standard_library_nat if any of 742 + the compilation units use %standard_library_default. The primitive is omitted 743 + completely in libasmrun as there are no other existing instances in the 744 + native runtime where OCAML_STDLIB_DIR ends up being embedded. */ 745 + #ifndef NATIVE_CODE 746 + /* If this remains unset then caml_runtime_standard_library_default is used */ 747 + char_os *caml_standard_library_default = NULL; 748 + 749 + CAMLprim value caml_sys_const_standard_library_default(value unit) 750 + { 751 + return caml_copy_string_of_os( 752 + caml_standard_library_default ? caml_standard_library_default 753 + : caml_runtime_standard_library_default); 754 + } 755 + #endif 756 + 757 + CAMLprim value caml_sys_get_stdlib_dirs(value vstdlib_default) 758 + { 759 + CAMLparam1(vstdlib_default); 760 + CAMLlocal3(result, eff, root_dir); 761 + 762 + char_os *stdlib_default = caml_stat_strdup_to_os(String_val(vstdlib_default)); 763 + char_os *root = NULL, *stdlib; 764 + 765 + stdlib = 766 + caml_locate_standard_library(caml_params->exe_name, stdlib_default, &root); 767 + 768 + eff = caml_copy_string_of_os(stdlib); 769 + if (root == NULL) { 770 + root_dir = Val_none; 771 + } else { 772 + root_dir = caml_copy_string_of_os(root); 773 + root_dir = caml_alloc_some(root_dir); 774 + } 775 + result = caml_alloc_2(0, eff, root_dir); 776 + 777 + CAMLreturn(result); 778 + } 779 + 739 780 CAMLprim value caml_sys_get_config(value unit) 740 781 { 741 782 CAMLparam0 (); /* unit is unused */
+70
runtime/unix.c
··· 54 54 #else 55 55 #include <sys/dir.h> 56 56 #endif 57 + #ifdef HAS_LIBGEN_H 58 + #include <libgen.h> 59 + #endif 57 60 #ifdef __APPLE__ 58 61 #include <mach-o/dyld.h> 59 62 #endif ··· 542 545 if (munmap(mem, size) != 0) 543 546 CAMLassert(0); 544 547 } 548 + 549 + static char * caml_dirname (const char * path) 550 + { 551 + #ifdef HAS_LIBGEN_H 552 + char *dir, *res; 553 + dir = caml_stat_strdup(path); 554 + res = caml_stat_strdup(dirname(dir)); 555 + caml_stat_free(dir); 556 + return res; 557 + #else 558 + /* See Filename.generic_dirname */ 559 + ptrdiff_t n = strlen(path) - 1; 560 + char *res; 561 + if (n < 0) /* path is "" */ 562 + return caml_stat_strdup("."); 563 + while (n >= 0 && path[n] == '/') 564 + n--; 565 + if (n < 0) /* path is entirely slashes */ 566 + return caml_stat_strdup("/"); 567 + while (n >= 0 && path[n] != '/') 568 + n--; 569 + if (n < 0) /* path is relative */ 570 + return caml_stat_strdup("."); 571 + while (n >= 0 && path[n] == '/') 572 + n--; 573 + if (n < 0) /* path is a file at root */ 574 + return caml_stat_strdup("/"); 575 + /* n is the _index_ of the last character of the dirname */ 576 + res = caml_stat_alloc(n + 2); 577 + memcpy(res, path, n + 1); 578 + res[n + 1] = 0; 579 + return res; 580 + #endif 581 + } 582 + 583 + CAMLextern char_os* caml_locate_standard_library (const char *exe_name, 584 + const char *stdlib_default, 585 + char **dirname) 586 + { 587 + if (Is_relative_dir(stdlib_default)) { 588 + char * root = caml_dirname(exe_name); 589 + char * candidate = 590 + caml_stat_strconcat(3, root, CAML_DIR_SEP, stdlib_default); 591 + /* In practice, a system which can be configured --with-relative-libdir will 592 + also have realpath. The directory is normalised here for consistency with 593 + the behaviour on Windows, which doesn't have a direct equivalent of 594 + dirname and performs the equivalent of realpath as a side-effect of 595 + determining the root path. */ 596 + #ifdef HAS_REALPATH 597 + char * resolved_candidate = realpath(candidate, NULL); 598 + /* If realpath fails, use the non-normalised path for error messages. */ 599 + if (resolved_candidate != NULL) { 600 + caml_stat_free(candidate); 601 + /* realpath uses malloc */ 602 + candidate = caml_stat_strdup(resolved_candidate); 603 + free(resolved_candidate); 604 + } 605 + #endif 606 + if (dirname == NULL) 607 + caml_stat_free(root); 608 + else 609 + *dirname = root; 610 + return candidate; 611 + } else { 612 + return caml_stat_strdup(stdlib_default); 613 + } 614 + }
+86
runtime/win32.c
··· 41 41 #include <errno.h> 42 42 #include <string.h> 43 43 #include <signal.h> 44 + #include <wchar.h> 44 45 #include "caml/alloc.h" 45 46 #include "caml/codefrag.h" 46 47 #include "caml/fail.h" ··· 1342 1343 caml_win32_sys_error(GetLastError()); 1343 1344 CAMLreturn(caml_copy_string_of_utf16(buf)); 1344 1345 } 1346 + 1347 + CAMLextern char_os* caml_locate_standard_library (const wchar_t *exe_name, 1348 + const wchar_t *stdlib_default, 1349 + wchar_t **dirname) 1350 + { 1351 + if (Is_relative_dir(stdlib_default)) { 1352 + LPWSTR root = NULL, basename; 1353 + DWORD l = MAX_PATH + 1, buf_len; 1354 + 1355 + do { 1356 + buf_len = l; 1357 + caml_stat_free(root); 1358 + root = caml_stat_alloc(buf_len * sizeof(WCHAR)); 1359 + l = GetFullPathName(exe_name, buf_len, root, &basename); 1360 + } while (l >= buf_len); 1361 + /* It should be an Impossible Thing for exe_name (which will have been the 1362 + result of GetModuleFileName) to be unparsable by GetFullPathName */ 1363 + if (l == 0) { 1364 + caml_stat_free(root); 1365 + return caml_stat_wcsdup(stdlib_default); 1366 + } 1367 + 1368 + CAMLassert(basename && basename != root && Is_separator(*(basename - 1))); 1369 + 1370 + /* Make root the dirname portion */ 1371 + *(basename - 1) = 0; 1372 + 1373 + LPWSTR candidate = 1374 + caml_stat_wcsconcat(3, root, CAML_DIR_SEP, stdlib_default); 1375 + HANDLE h = 1376 + CreateFile(candidate, 0, 1377 + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 1378 + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 1379 + if (h == INVALID_HANDLE_VALUE) { 1380 + caml_stat_free(candidate); 1381 + return caml_stat_wcsdup(stdlib_default); 1382 + } 1383 + 1384 + LPWSTR resolved_candidate = NULL; 1385 + l = MAX_PATH + 1; 1386 + do { 1387 + buf_len = l; 1388 + caml_stat_free(resolved_candidate); 1389 + resolved_candidate = caml_stat_alloc(buf_len * sizeof(WCHAR)); 1390 + l = GetFinalPathNameByHandle(h, resolved_candidate, buf_len, 1391 + FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 1392 + } while (l >= buf_len); 1393 + 1394 + if (l > 0) { 1395 + /* GetFinalPathNameByHandle always returns \\?\ which needs stripping. */ 1396 + CAMLassert(l > 4 && resolved_candidate[0] == '\\' 1397 + && resolved_candidate[1] == '\\' 1398 + && resolved_candidate[2] == '?' 1399 + && resolved_candidate[3] == '\\'); 1400 + 1401 + caml_stat_free(candidate); 1402 + 1403 + if (l >= 8 && resolved_candidate[4] == 'U' 1404 + && resolved_candidate[5] == 'N' 1405 + && resolved_candidate[6] == 'C' 1406 + && resolved_candidate[7] == '\\') { 1407 + /* NT native UNC path (\\?\UNC\foo). We change the last C to a backslash 1408 + (\\?\UN\\foo) and then include that altered character and the 1409 + original final slash to create a normal UNC path. */ 1410 + resolved_candidate[6] = '\\'; 1411 + candidate = caml_stat_wcsdup(resolved_candidate + 6); 1412 + } else { 1413 + /* Local device path */ 1414 + candidate = caml_stat_wcsdup(resolved_candidate + 4); 1415 + } 1416 + } 1417 + 1418 + /* It should be another Impossible Thing for l == 0 in the above. If that 1419 + did happen, candidate will _not_ have been freed, and we'll return the 1420 + path returned by GetFullPathName */ 1421 + caml_stat_free(resolved_candidate); 1422 + 1423 + if (dirname != NULL) 1424 + *dirname = caml_stat_wcsdup(root); 1425 + caml_stat_free(root); 1426 + return candidate; 1427 + } else { 1428 + return caml_stat_wcsdup(stdlib_default); 1429 + } 1430 + }
+1 -1
testsuite/in_prefix/Makefile.test
··· 23 23 endif 24 24 25 25 DRIVER_ARGS = \ 26 - $(VERBOSE_FLAG) --bindir "$(BINDIR)" --libdir "$(LIBDIR)" \ 26 + $(VERBOSE_FLAG) --bindir "$(BINDIR)" --libdir '$(TARGET_LIBDIR)' \ 27 27 $(call bool_to_with, ocamlnat, $(INSTALL_OCAMLNAT)) \ 28 28 $(call bool_to_with, ocamlopt, $(NATIVE_COMPILER)) \ 29 29 $(OTHERLIBRARIES) --pwd "$(SRCDIR_ABS)/testsuite/in_prefix"
+6 -3
testsuite/in_prefix/README.md
··· 46 46 During this second execution, the test harness does whatever is physically 47 47 possible to allow these tests to proceed: 48 48 - Environment variables `CAML_LD_LIBRARY_PATH` and `OCAMLLIB` are manipulated to 49 - allow the compiler to operate 49 + allow the compiler to operate (unless the compiler has been configured with 50 + `--with-relative-libdir`) 50 51 - Bytecode executables which will no longer be able to find `ocamlrun` are 51 52 explicitly passed to `ocamlrun`. The harness always verifies that this step is 52 53 required by first executing the binary and ensuring that it fails and then ··· 72 73 - On Unix, the bytecode toplevel contains the absolute location of `ocamlrun`, 73 74 so must be explicitly invoked via `ocamlrun` 74 75 - Both toplevels contain the absolute location of the Standard Library, 75 - requiring `OCAMLLIB` to be set 76 + requiring `OCAMLLIB` to be set, unless the compiler was configured with 77 + `--with-relative-libdir` 76 78 77 79 ### Loading archives/plugins (.cma / .cmxs) with `Dynlink` 78 80 ··· 84 86 compiler is available, then both `ocamlc` and `ocamlopt` will be native 85 87 executables) 86 88 - Both compilers contain the absolute location of the Standard Library, 87 - requiring `OCAMLLIB` to be set 89 + requiring `OCAMLLIB` to be set, unless the comnpiler was configured with 90 + `--with-relative-libdir` 88 91 - The executable created by `ocamlc` contains the absolute location of 89 92 `ocamlrun`, so must be both explicitly invoked via `ocamlrun` and also have 90 93 `CAML_LD_LIBRARY_PATH` or `OCAMLLIB` adjusted, as that `ocamlrun` will not be
+1
testsuite/tests/native-debugger/linux-lldb-amd64.ml
··· 1 1 (* TEST 2 + unset BUILD_PATH_PREFIX_MAP; 2 3 native-compiler; 3 4 no-tsan; (* Skip, TSan inserts extra frames into backtraces *) 4 5 linux;
+1
testsuite/tests/native-debugger/linux-lldb-arm64.ml
··· 1 1 (* TEST 2 + unset BUILD_PATH_PREFIX_MAP; 2 3 native-compiler; 3 4 no-tsan; (* Skip, TSan inserts extra frames into backtraces *) 4 5 linux;
+1
testsuite/tests/tool-debugger/find-artifacts/debuggee.ml
··· 1 1 (* TEST 2 + unset BUILD_PATH_PREFIX_MAP; 2 3 debugger_script = "${test_source_directory}/input_script"; 3 4 debugger; 4 5 shared-libraries;
+1 -1
testsuite/tools/cmdline.ml
··· 176 176 "--pwd", Arg.Set_string pwd, "<pwd>\tCurrent working directory to use"; 177 177 "--bindir", Arg.String (check_exists ~absolute:true bindir), "\ 178 178 <bindir>\tDirectory containing programs (must share a prefix with --libdir)"; 179 - "--libdir", Arg.String (check_exists ~absolute:true libdir), "\ 179 + "--libdir", Arg.String (check_exists ~absolute:false libdir), "\ 180 180 <libdir>\tDirectory containing stdlib.cma (must share a prefix with --bindir)"; 181 181 "--summary", Arg.Set summary, ""; 182 182 "--verbose", Arg.Set verbose, "";
+2 -1
testsuite/tools/harness.mli
··· 53 53 has_ocamlopt: bool; 54 54 (** {v [$(NATIVE_COMPILER)] v} - {v Makefile.config v} *) 55 55 has_relative_libdir: string option; 56 - (** Not implemented; always None. *) 56 + (** {v $(TARGET_LIBDIR_IS_RELATIVE) v} and {v $(TARGET_LIBDIR) v} - 57 + {v Makefile.build_config v} *) 57 58 has_runtime_search: bool option; 58 59 (** Not implemented; always None. *) 59 60 launcher_searches_for_ocamlrun: bool;
+7 -4
testsuite/tools/testBytecodeBinaries.ml
··· 44 44 if classification <> Vanilla then 45 45 let fails = 46 46 (* After the prefix has been renamed, bytecode executables compiled 47 - with -custom will still work. Otherwise, only executables where the 48 - header can search for ocamlrun and which do not require any C stubs 49 - to be loaded will still work. *) 47 + with -custom will still work. Otherwise, the header needs to be 48 + able to search for ocamlrun and, if applicable, ocamlrun needs to 49 + be able to load C stubs (which will only happen if the runtime 50 + locates the Standard Library using a relative directory, so that it 51 + can find ld.conf) *) 50 52 Environment.is_renamed env 51 53 && match classification with 52 54 | Tendered {dlls; _} -> 53 - not config.launcher_searches_for_ocamlrun || dlls 55 + not config.launcher_searches_for_ocamlrun 56 + || dlls && config.has_relative_libdir = None 54 57 | _ -> 55 58 false 56 59 in
+27 -8
testsuite/tools/testDynlink.ml
··· 48 48 let compile ?(custom = false) () = 49 49 if Sys.file_exists test_program then 50 50 Harness.erase_file test_program; 51 - let args = if custom then "-custom" :: args else args in 51 + let args = 52 + if custom then 53 + "-custom" :: args 54 + else 55 + (* Hardening to ensure that Bytecode Dynlink is using the runtime's 56 + search path, not compiler's (i.e. unix.cma should be located using 57 + Config.standard_library_default but dllunixbyt.so should be located 58 + using caml_runtime_standard_library_default) *) 59 + "-set-runtime-default" :: "standard_library_default=/does-not-exist" 60 + :: args 61 + in 52 62 (* In the Renamed phase for a bytecode-only build, ocamlc will be 53 63 ocamlc.byte and will need to be called via ocamlrun *) 54 64 let runtime = 55 65 mode = Bytecode && Harness.ocamlc_fails_after_rename config in 56 66 (* In the Renamed phase, Config.standard_library will still point to the 57 - Original location *) 58 - let stdlib = true in 67 + Original location, unless the compiler has been configured with a 68 + relative libdir *) 69 + let stdlib = (config.has_relative_libdir = None) in 59 70 let (_, output) = 60 71 Environment.run_process ~runtime ~stdlib env compiler args in 61 72 Environment.display_output output ··· 78 89 mode = Bytecode 79 90 && expected_exit_code = None 80 91 && not config.target_launcher_searches_for_ocamlrun 92 + && config.has_relative_libdir = None 81 93 in 82 94 (* If the library needs C stubs to be loaded dynamically, then the runtime 83 95 will need CAML_LD_LIBRARY_PATH set in the Renamed phase. *) 84 96 let stubs = 85 97 has_c_stubs 86 98 && expected_exit_code = None 99 + && Config.supports_shared_libraries 100 + && config.has_relative_libdir = None 87 101 in 88 102 let expected_exit_code = 89 103 match expected_exit_code with ··· 126 140 let not_dynlink l = not (List.mem "dynlink" l) in 127 141 let files, re_compile = compile_test_program () in 128 142 let expected_exit_code = 129 - (* Bytecode executables launched using the executable header require 130 - caml_executable_name to know where the runtime is. As the Standard 131 - Library is only stored as an absolute path, this doesn't affect the 132 - execution of the test driver (yet). *) 133 - None in 143 + (* Relocatable OCaml bytecode executables launched using the executable 144 + header require caml_executable_name, or they end up being accidentally 145 + relative, since the exec call leaves argv[0] as being the bytecode image 146 + itself. *) 147 + if mode = Bytecode && config.has_relative_libdir <> None 148 + && Harness.no_caml_executable_name 149 + && Environment.launched_via_stub test_program then 150 + Some 2 151 + else 152 + None in 134 153 let libraries = List.filter not_dynlink config.libraries in 135 154 let () = 136 155 List.iter (test_libraries_in_prog ?expected_exit_code env) libraries;
+49 -18
testsuite/tools/testLinkModes.ml
··· 125 125 around some problems with shared runtimes on s390x and riscv which don't 126 126 reliably fail. 127 127 *) 128 - let run_program env _config = 128 + let run_program env config = 129 129 let prefix = Environment.prefix env in 130 130 let libdir_suffix = Environment.libdir_suffix env in 131 131 let prefix, libdir_suffix = ··· 142 142 if Environment.is_renamed env then 143 143 stdlib_exists_when_renamed 144 144 else 145 - true in 145 + config.has_relative_libdir <> None in 146 146 let args = [string_of_bool stdlib_exists; prefix; libdir_suffix] in 147 147 let argv0 = 148 148 if argv0 = test_program then ··· 259 259 - Sys.argv.(0) doesn't equal Sys.argv.(3) 260 260 - Config.standard_library exists when it shouldn't (or vice versa) *) 261 261 let test_runs usr_bin_sh test_program_path test_program 262 - _config env ~via_ocamlrun = 262 + config env ~via_ocamlrun = 263 263 let tests = 264 264 let test_program_relative = 265 265 Filename.concat Filename.current_dir_name test_program ··· 315 315 else if Sys.win32 then 316 316 (* stdlib/header.c correctly preserves argv[0] for Windows *) 317 317 Success {executable_name = test_program_path; argv0} 318 + else if Harness.no_caml_executable_name 319 + && config.has_relative_libdir <> None then 320 + (* Without caml_executable_name, ocamlrun will be forced to 321 + interpret the relative standard library relative to argv[0], 322 + which will fail. *) 323 + Fail 134 318 324 else 319 325 (* stdlib/header.c does not preserve argv[0] for Unix *) 320 326 Success {executable_name = argv0_resolved; ··· 329 335 else 330 336 Success {executable_name = argv0_resolved; argv0} 331 337 else 332 - if Sys.win32 || argv0_not_ocaml then 333 - (* SearchPath will resolve the relative/implicit arguments to 334 - absolute paths *) 335 - Success {executable_name = test_program_path; argv0} 336 - else 337 - Success {executable_name = argv0_resolved; argv0} 338 + (* -custom executables use caml_executable_name *) 339 + Success {executable_name = test_program_path; argv0} 338 340 | Vanilla -> 339 341 if Harness.no_caml_executable_name then 340 342 Success {executable_name = argv0_resolved; argv0} ··· 355 357 run in the Renamed phase for other reasons. *) 356 358 let make_test_runner ~stdlib_exists_when_renamed ~may_segfault ~with_unix 357 359 ~tendered ~target_launcher_searches_for_ocamlrun usr_bin_sh 358 - test_program_path test_program config _env = 359 - (* Bytecode executables with absolute headers will need to be 360 - invoked via ocamlrun after the prefix has been renamed. *) 360 + test_program_path test_program config env = 361 + (* Bytecode executables with absolute headers will need to be invoked via 362 + ocamlrun after the prefix has been renamed. *) 361 363 let via_ocamlrun = 362 364 tendered && not target_launcher_searches_for_ocamlrun 365 + && (config.has_relative_libdir = None || not (Environment.is_renamed env)) 363 366 in 364 367 let rec run env = 365 368 let runs = ··· 371 374 | Fail code -> "", code, "" 372 375 | Success {executable_name; argv0} -> executable_name, 0, argv0 373 376 in 374 - let stubs = tendered && with_unix in 377 + let stubs = tendered && with_unix && config.has_relative_libdir = None in 375 378 run_program 376 379 env config ~runtime:via_ocamlrun ~stubs 377 380 test_program_path ~prefix_path_with_cwd expected_executable_name ··· 566 569 else 567 570 options 568 571 in 572 + let options = 573 + if Environment.is_renamed env || config.has_relative_libdir <> None then 574 + options 575 + else 576 + let new_libdir = 577 + Filename.concat (Environment.prefix env ^ ".new") 578 + (Environment.libdir_suffix env) in 579 + let stdlib_default = "standard_library_default=" ^ new_libdir in 580 + let options = "-set-runtime-default" :: stdlib_default :: options in 581 + if tendered then 582 + let libdir = Environment.libdir env in 583 + "-dllpath" :: (Filename.concat libdir "stublibs") :: options 584 + else 585 + options 586 + in 569 587 let args = 570 588 "-o" :: output :: 571 589 "test_install_script.ml" :: options ··· 593 611 let runtime = 594 612 mode = Bytecode && Harness.ocamlc_fails_after_rename config in 595 613 (* In the Renamed phase, Config.standard_library will still point to 596 - the Original location *) 597 - let stdlib = true in 614 + the Original location, unless the compiler has been configured 615 + with a relative libdir *) 616 + let stdlib = (config.has_relative_libdir = None) in 598 617 Environment.run_process ~fails ~runtime ~stdlib env compiler args 599 618 in 600 619 Environment.display_output output; ··· 622 641 `None 623 642 else 624 643 let stdlib_exists_when_renamed = 625 - (* Config.standard_library is an absolute path, and therefore will 626 - always point to the Original location in the Renamed phase. *) 627 - false 644 + if config.has_relative_libdir = None then 645 + (* In the Original phase, for a compiler with an absolute libdir, 646 + -set-runtime-default is used to set standard_library_default to 647 + the Renamed phase's location. When the tests are recompiled in 648 + the Renamed phase, this is not done. The effect is that if any 649 + test is being run in the Renamed phase, Config.standard_library 650 + will be correct. *) 651 + not (Environment.is_renamed env) 652 + else 653 + (* When the compiler has a relative libdir, -set-runtime-default 654 + is implicitly being tested by the build process, and we wish to 655 + test the opposite in the harness - thus the test programs 656 + compiled in the Original phase will _not_ be able to find the 657 + Standard Library in the Renamed phase. *) 658 + Environment.is_renamed env 628 659 in 629 660 make_test_runner ~stdlib_exists_when_renamed ~may_segfault ~with_unix 630 661 ~tendered ~target_launcher_searches_for_ocamlrun
+40 -28
testsuite/tools/testRelocation.ml
··· 24 24 (* Augment toolchain properties with information from the configuration (this 25 25 essentially goes from "is foo capable of doing bar" to "foo does bar in this 26 26 context". *) 27 - let effective_toolchain _config = 27 + let effective_toolchain config = 28 28 let c_compiler_debug_paths_are_absolute = 29 29 Toolchain.c_compiler_debug_paths_can_be_absolute 30 + && (not Config.c_has_debug_prefix_map || config.has_relative_libdir = None) 30 31 in 31 32 let assembler_embeds_build_path = 32 33 Toolchain.assembler_embeds_build_path 34 + && (not Config.as_has_debug_prefix_map 35 + || Config.architecture = "riscv" 36 + || Config.as_is_cc 37 + || config.has_relative_libdir = None) 33 38 in 34 39 ~c_compiler_debug_paths_are_absolute, ~assembler_embeds_build_path 35 40 ··· 59 64 (* Determine if the installation prefix should be found in this file *) 60 65 let prefix = 61 66 let code_embeds_stdlib_location = 62 - (* The runtime binaries all contain OCAML_STDLIB_DIR and everything 63 - except flexlink and ocamllex link with the Config module, either 64 - directly or via ocamlcommon *) 65 - not (List.mem basename ["flexlink.byte"; "flexlink.opt"; "flexlink"; 66 - "ocamllex.byte"; "ocamllex.opt"; "ocamllex"; 67 - "ocamlyacc"]) 67 + (* If the compiler is configured with an absolute libdir, the runtime 68 + binaries all contain OCAML_STDLIB_DIR and everything except flexlink 69 + and ocamllex link with the Config module, either directly or via 70 + ocamlcommon *) 71 + config.has_relative_libdir = None 72 + && not (List.mem basename ["flexlink.byte"; "flexlink.opt"; "flexlink"; 73 + "ocamllex.byte"; "ocamllex.opt"; "ocamllex"; 74 + "ocamlyacc"]) 68 75 in 69 76 let linker_embeds_stdlib_location = 70 77 (* If the launcher doesn't search for ocamlrun, then either the #! stub ··· 124 131 stripped. However, since the C objects in libcamlrun are compiled 125 132 with -g, this will still result in debug information for -custom 126 133 runtime executables. *) 127 - linked_with_debug 134 + linked_with_debug && config.has_relative_libdir = None 128 135 || (classification = Custom 129 136 && Toolchain.linker_propagates_debug_information 130 137 && c_compiler_debug_paths_are_absolute) ··· 160 167 ~ocaml_debug:has_ocaml_debug_info, 161 168 ~c_debug:has_c_debug_info, 162 169 ~s:contains_assembled_objects) = 163 - if basename = "Makefile.config" || basename = "runtime-launch-info" then 164 - (* These files all embed the Standard Library location *) 170 + if basename = "Makefile.config" then 171 + (* Embeds the Standard Library location *) 165 172 (~stdlib:true, ~ocaml_debug:false, ~c_debug:false, ~s:false) 166 173 else if basename = "config.cmx" then 167 174 (* config.cmx contains Config.standard_library for inlining *) 168 - (~stdlib:true, ~ocaml_debug:false, ~c_debug:false, ~s:false) 175 + let stdlib = 176 + config.has_relative_libdir = None && not Config.flambda in 177 + (~stdlib, ~ocaml_debug:false, ~c_debug:false, ~s:false) 169 178 else if List.mem ext [".cma"; ".cmo"; ".cmt"; ".cmti"] then 170 179 let stdlib = (* via Config.standard_library *) 171 - List.mem basename ["config.cmt"; "config_main.cmt"; 172 - "ocamlcommon.cma"] in 180 + config.has_relative_libdir = None 181 + && List.mem basename ["config.cmt"; "config_main.cmt"; 182 + "ocamlcommon.cma"] in 183 + (* The compiler's artefacts are all compiled with -g *) 173 184 (~stdlib, ~ocaml_debug:true, ~c_debug:false, ~s:false) 185 + else if basename = "runtime-launch-info" then 186 + (* When the compiler is configured with a relative libdir, 187 + runtime-launch-info just contains ".", rather than the prefix *) 188 + let stdlib = (config.has_relative_libdir = None) in 189 + (~stdlib, ~ocaml_debug:false, ~c_debug:false, ~s:false) 174 190 else if ext = ".cmxs" then 175 191 (* All the .cmxs files built by the distribution at present include C 176 192 objects and obviously contain assembled objects. *) ··· 185 201 not (is_ocaml || String.starts_with ~prefix:"flexdll_" basename) in 186 202 (~stdlib:false, ~ocaml_debug:false, ~c_debug, ~s:is_ocaml) 187 203 else if ext = Config.ext_lib || ext = Config.ext_dll then 188 - (* Based on the filename, is this one of the bytecode runtime libraries 189 - (libcamlrun.a, libcamlrund.a, libcamlrun_shared.so, etc. 190 - Note that these properties are _not_ used for libasmrun* (see 191 - below) *) 192 - let is_camlrun = 193 - let dir = Filename.basename (Filename.dirname file) in 194 - dir <> "stublibs" 195 - && String.starts_with ~prefix:"libcamlrun" basename 196 - && not (String.starts_with ~prefix:"libcamlruntime" basename) 197 - in 198 204 if ext = Config.ext_lib then 199 205 (* Any archive produced by ocamlopt will have a .cmxa file with it *) 200 206 let is_ocaml = ··· 202 208 (* Config.standard_library is in ocamlcommon and the bytecode runtime 203 209 embeds the Standard Library location *) 204 210 let stdlib = 205 - is_camlrun 206 - || Filename.remove_extension basename = "ocamlcommon" 207 - in 211 + config.has_relative_libdir = None 212 + && Filename.remove_extension basename = "ocamlcommon" in 208 213 (~stdlib, ~ocaml_debug:false, ~c_debug:(not is_ocaml), ~s:is_ocaml) 209 214 else 210 215 (* DLLs are either the shared versions of the runtime libraries or 211 216 C stubs. All of these are compiled with -g *) 212 - (~stdlib:is_camlrun, ~ocaml_debug:false, ~c_debug:true, ~s:false) 217 + (~stdlib:false, ~ocaml_debug:false, ~c_debug:true, ~s:false) 213 218 else 214 219 (~stdlib:false, ~ocaml_debug:false, ~c_debug:false, ~s:false) 215 220 in ··· 227 232 || Toolchain.linker_embeds_build_path) then 228 233 Toolchain.linker_embeds_build_path 229 234 else 230 - has_ocaml_debug_info 235 + has_ocaml_debug_info && config.has_relative_libdir = None 231 236 || has_c_debug_info && c_compiler_debug_paths_are_absolute 232 237 || contains_assembled_objects && assembler_embeds_build_path 233 238 || ext = Config.ext_obj ··· 238 243 LocationSet.singleton Prefix 239 244 else 240 245 LocationSet.empty 246 + in 247 + let prefix = 248 + if config.has_relative_libdir <> None 249 + && basename = "Makefile.config" then 250 + LocationSet.add Relative prefix 251 + else 252 + prefix 241 253 in 242 254 if contains_build_path then 243 255 LocationSet.add Build prefix
+1 -1
testsuite/tools/testToplevel.ml
··· 97 97 Environment.run_process 98 98 ~fails:(expected_exit_code <> 0) 99 99 ~runtime:(mode = Bytecode && not config.launcher_searches_for_ocamlrun) 100 - ~stdlib:true env toplevel args 100 + ~stdlib:(config.has_relative_libdir = None) env toplevel args 101 101 in 102 102 Environment.display_output output; 103 103 if exit_code <> expected_exit_code then
+5 -5
testsuite/tools/test_in_prefix.ml
··· 144 144 145 145 For the compiler's files to be reproducible, the compiler needs to be both 146 146 relocatable and also required support from the assembler and C compiler. *) 147 - let relocatable = false in 147 + let relocatable = 148 + config.has_relative_libdir <> None 149 + && config.launcher_searches_for_ocamlrun 150 + in 148 151 let reproducible = 149 152 relocatable 150 - (* At present, the compiler build doesn't actually take advantage of this 151 - configuration, but this does not matter because the compiler cannot yet 152 - be relocatable! *) 153 153 && (not config.has_ocamlopt 154 154 || not Toolchain.assembler_embeds_build_path 155 155 || Config.as_has_debug_prefix_map && Config.architecture <> "riscv") ··· 157 157 && (not Toolchain.c_compiler_always_embeds_build_path 158 158 || not Toolchain.c_compiler_debug_paths_can_be_absolute) 159 159 in 160 - let target_relocatable = false in 160 + let target_relocatable = config.target_launcher_searches_for_ocamlrun in 161 161 (* Use Harness.pp_path unless --verbose was specified *) 162 162 let pp_path = 163 163 if verbose then
+19 -7
testsuite/tools/test_ld_conf.ml
··· 39 39 and var_setting = Unset | Empty | Set of string list 40 40 41 41 (* Set of tests to run in a given environment *) 42 - let tests _config env = 42 + let tests config env = 43 43 (* Convenience function - [if_ld_conf_found outcome] returns the empty list in 44 44 the Renamed phase. *) 45 45 let if_ld_conf_found outcome = 46 - (* ocamlrun can't find ld.conf after the prefix has been renamed *) 47 - if Environment.is_renamed env then 46 + (* ocamlrun can only find ld.conf after the prefix has been renamed if it's 47 + configured with --with-relative-libdir *) 48 + if Environment.is_renamed env && config.has_relative_libdir = None then 48 49 [] 49 50 else 50 51 outcome ··· 63 64 Environment.libdir env 64 65 else 65 66 Config.standard_library in 67 + let libdir = 68 + if config.has_relative_libdir = None then 69 + libdir 70 + else 71 + (* Unix.realpath raises Invalid_argument if it's not available *) 72 + try Unix.realpath libdir 73 + with Invalid_argument _ -> libdir in 66 74 let (/) = Filename.concat in 67 75 let data = [ 68 76 (* Root directory (both forms) preserved *) ··· 326 334 let runtime = 327 335 mode = Bytecode && Harness.ocamlc_fails_after_rename config in 328 336 (* In the Renamed phase, Config.standard_library will still point to the 329 - Original location *) 330 - let stdlib = true in 337 + Original location, unless the compiler has been configured with a 338 + relative libdir *) 339 + let stdlib = (config.has_relative_libdir = None) in 331 340 let (_, output) = 332 341 Environment.run_process ~runtime ~stdlib env compiler args in 333 342 Environment.display_output output; ··· 342 351 in 343 352 (* In the Renamed phase, the test driver will need to be launched with 344 353 ocamlrun, unless executables produced by the compiler are capable of 345 - searching for the runtime (as the Windows executable launcher does) *) 354 + searching for the runtime (as the Windows executable launcher does) or 355 + the compiler has been configured with a relative libdir (as in this mode 356 + the bytecode header will have the correct location) *) 346 357 let runtime = 347 358 mode = Bytecode 348 - && not config.target_launcher_searches_for_ocamlrun in 359 + && not config.target_launcher_searches_for_ocamlrun 360 + && config.has_relative_libdir = None in 349 361 let run run_process test = 350 362 let code, lines = 351 363 run_process ~runtime test_program []
+83
tools/ci/actions/runner.sh
··· 128 128 $MAKE install 129 129 } 130 130 131 + target_libdir_is_relative='^ *TARGET_LIBDIR_IS_RELATIVE *= *false' 132 + 131 133 Test-In-Prefix () { 134 + { set +x 135 + echo 'Checking that compilers invoked with alternate runtimes use their' 136 + echo "configured location, not the alternate runtime's" 137 + expected1="$(realpath "$PREFIX/lib/ocaml")" 138 + } 2>/dev/null 139 + if [[ ! -d "$PREFIX.new" ]]; then 140 + # In Re-Test-In-Prefix, $PREFIX is the original compiler built by the 141 + # workflow and then $PREFIX.new is the "alternate configuration". The first 142 + # time round, we clone whichever compiler has just been built for this test. 143 + cp -a "$PREFIX" "$PREFIX.new" 144 + remove="$PREFIX.new" 145 + if grep -q "$target_libdir_is_relative" Makefile.build_config; then 146 + # Compiler configured absolutely - both should return the same answer 147 + expected2="$expected1" 148 + else 149 + # Compiler configured relatively 150 + expected2="$(realpath "$PREFIX").new/lib/ocaml" 151 + fi 152 + else 153 + # The alternate configuration path should be returned, regardless of whether 154 + # the runtime invoking it is an absolute or a relative one from another 155 + # location. 156 + expected2="$(realpath "$PREFIX").new/lib/ocaml-lib" 157 + remove='' 158 + fi 159 + { set +x 160 + lib1="$($PREFIX.new/bin/ocamlrun $PREFIX/bin/ocamlc.byte -where)" 161 + lib2="$($PREFIX/bin/ocamlrun $PREFIX.new/bin/ocamlc.byte -where)" 162 + echo "$PREFIX/bin/ocamlc.byte OSLD: $($PREFIX/bin/ocamlrun \ 163 + $PREFIX/bin/ocamlobjinfo.byte $PREFIX/bin/ocamlc.byte \ 164 + | sed -ne 's/^caml_standard_library_default: //p')" 165 + echo -n "$PREFIX.new/bin/ocamlrun standard_library_default: " 166 + $PREFIX.new/bin/ocamlrun -config | sed -ne 's/standard_library_default: //p' 167 + echo "$PREFIX.new/bin/ocamlrun $PREFIX/bin/ocamlc.byte -where: $lib1" 168 + if [[ $lib1 != $expected1 ]]; then 169 + echo -e ' \e[31mEXPECTED\e[0m:' "$expected1" 170 + fi 171 + echo 172 + echo "$PREFIX.new/bin/ocamlc.byte OSLD: $($PREFIX.new/bin/ocamlrun \ 173 + $PREFIX.new/bin/ocamlobjinfo.byte $PREFIX.new/bin/ocamlc.byte \ 174 + | sed -ne 's/^caml_standard_library_default: //p')" 175 + echo -n "$PREFIX/bin/ocamlrun standard_library_default: " 176 + $PREFIX/bin/ocamlrun -config | sed -ne 's/standard_library_default: //p' 177 + echo "$PREFIX/bin/ocamlrun $PREFIX.new/bin/ocamlc.byte -where: $lib2" 178 + if [[ $lib2 != $expected2 ]]; then 179 + echo -e ' \e[31mEXPECTED\e[0m:' "$expected2" 180 + fi 181 + [[ $lib1 = $expected1 && $lib2 = $expected2 ]] && echo 'Correct.' || exit 1 182 + } 2>/dev/null 183 + [[ -z $remove ]] || rm -rf "$remove" 132 184 $MAKE -C testsuite/in_prefix -f Makefile.test test-in-prefix 185 + } 186 + 187 + Re-Test-In-Prefix () { 188 + mkdir -p bak 189 + mv Makefile.config Makefile.build_config config.status bak 190 + git clean -dfX &>/dev/null 191 + mv bak/Makefile.config bak/Makefile.build_config bak/config.status . 192 + rmdir bak 193 + # The libdir is configured to be $PREFIX.new/lib/ocaml-lib in order to 194 + # "poison" the cross-runtime test (otherwise if $PREFIX/bin/ocamlc.byte is 195 + # missing OSLD, then $PREFIX.new/bin/ocamlrun would still supply the correct 196 + # ../lib/ocaml. This way, it supplies ../lib/ocaml-lib and the test correctly 197 + # fails) 198 + if grep -q "$target_libdir_is_relative" Makefile.build_config; then 199 + # Compiler configured absolutely - reconfigure relatively 200 + echo '::group::Re-building the compiler with a relative libdir' 201 + $MAKE COMPUTE_DEPS=false reconfigure \ 202 + 'ADDITIONAL_CONFIGURE_ARGS=--with-relative-libdir=../lib/ocaml-lib \ 203 + --prefix='"$PREFIX"'.new' 204 + else 205 + # Compiler configured relatively - reconfigure absolutely 206 + echo '::group::Re-building the compiler with an absolute libdir' 207 + $MAKE COMPUTE_DEPS=false reconfigure \ 208 + 'ADDITIONAL_CONFIGURE_ARGS=--without-relative-libdir \ 209 + --prefix='"$PREFIX"'.new --libdir='"$PREFIX"'.new/lib/ocaml-lib' 210 + fi 211 + $MAKE 212 + $MAKE install 213 + echo '::endgroup::' 214 + Test-In-Prefix 133 215 } 134 216 135 217 Checks () { ··· 223 305 api-docs) API_Docs;; 224 306 install) Install;; 225 307 test-in-prefix) Test-In-Prefix;; 308 + re-test-in-prefix) Re-Test-In-Prefix;; 226 309 manual) BuildManual;; 227 310 other-checks) Checks;; 228 311 basic-compiler) BasicCompiler;;
+3 -1
tools/ci/appveyor/appveyor_build.sh
··· 76 76 args+=('--host=x86_64-pc-windows' '--enable-dependency-generation' \ 77 77 '--enable-native-toplevel');; 78 78 esac 79 + if [[ $RELOCATABLE = 'true' ]]; then 80 + args+=('--with-relative-libdir') 81 + fi 79 82 80 83 # Remove old configure cache if the configure script or the OS 81 84 # have changed ··· 99 102 PARALLEL_URL='https://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel' 100 103 APPVEYOR_BUILD_FOLDER=$(echo "$APPVEYOR_BUILD_FOLDER" | cygpath -f -) 101 104 FLEXDLLROOT="$PROGRAMFILES/flexdll" 102 - OCAMLROOT=$(echo "$OCAMLROOT" | cygpath -f - -m) 103 105 104 106 if [[ $BOOTSTRAP_FLEXDLL = 'false' ]] ; then 105 107 case "$PORT" in
+13 -4
tools/objinfo.ml
··· 35 35 36 36 module Magic_number = Misc.Magic_number 37 37 38 + let yesno_of_bool oc b = output_string oc (if b then "YES" else "no") 39 + 38 40 let dummy_crc = String.make 32 '-' 39 41 let null_crc = String.make 32 '0' 40 42 ··· 67 69 printf "YES\n"; 68 70 printf "Primitives declared in this module:\n"; 69 71 List.iter print_line l); 70 - printf "Force link: %s\n" (if cu.cu_force_link then "YES" else "no") 72 + printf "Force link: %a\n" yesno_of_bool cu.cu_force_link 71 73 72 74 let print_spaced_string s = 73 75 printf " %s" s 74 76 75 77 let print_cma_infos (lib : Cmo_format.library) = 76 - printf "Force custom: %s\n" (if lib.lib_custom then "YES" else "no"); 78 + printf "Force custom: %a\n" yesno_of_bool lib.lib_custom; 77 79 printf "Extra C object files:"; 78 80 (* PR#4949: print in linking order *) 79 81 List.iter print_spaced_string (List.rev lib.lib_ccobjs); ··· 249 251 printf "Currying functions:%a\n" pr_funs ui.ui_curry_fun; 250 252 printf "Apply functions:%a\n" pr_funs ui.ui_apply_fun; 251 253 printf "Send functions:%a\n" pr_funs ui.ui_send_fun; 252 - printf "Force link: %s\n" (if ui.ui_force_link then "YES" else "no"); 254 + printf "Force link: %a\n" yesno_of_bool ui.ui_force_link; 253 255 printf "For pack: %s\n" 254 256 (match ui.ui_for_pack with 255 257 | None -> "no" 256 - | Some pack -> "YES: " ^ pack) 258 + | Some pack -> "YES: " ^ pack); 259 + printf 260 + "Requires caml_standard_library_nat: %a\n" yesno_of_bool ui.ui_need_stdlib 257 261 258 262 let print_cmxa_infos (lib : Cmx_format.library_infos) = 259 263 printf "Extra C object files:"; ··· 317 321 | SYMB -> 318 322 let symb = Bytesections.read_section_struct toc ic section in 319 323 print_global_table symb 324 + | OSLD -> 325 + let caml_standard_library_default = 326 + Bytesections.read_section_string toc ic section in 327 + printf "caml_standard_library_default: %s\n" 328 + caml_standard_library_default 320 329 | _ -> () 321 330 with _ -> () 322 331 )
+1 -3
tools/ocamlmklib.ml
··· 25 25 Printf.sprintf "link -lib -nologo %s-out:%s %s %s" machine out opts files 26 26 else Printf.sprintf "%s rcs %s %s %s" Config.ar out opts files 27 27 28 - (* PR#4783: under Windows, don't use absolute paths because we do 29 - not know where the binary distribution will be installed. *) 30 28 let compiler_path name = 31 - if Sys.os_type = "Win32" then name else Filename.concat Config.bindir name 29 + Filename.concat Config.bindir name 32 30 33 31 let bytecode_objs = ref [] (* .cmo,.cma,.ml,.mli files to pass to ocamlc *) 34 32 and native_objs = ref [] (* .cmx,.ml,.mli files to pass to ocamlopt *)
+7 -1
utils/ccomp.ml
··· 90 90 ("", "") in 91 91 let debug_prefix_map = 92 92 match stable_name with 93 - | Some stable when Config.c_has_debug_prefix_map -> 93 + | Some stable 94 + when Config.c_has_debug_prefix_map 95 + && not (String.starts_with ~prefix:"mingw" Config.system) -> 96 + (* -fdebug-prefix-map exists on mingw-w64 but at present it is not used 97 + for BUILD_PATH_PREFIX_MAP because there isn't yet a good story for how 98 + to deal with Cygwin, where the paths are Cygwin-style paths and MSYS2, 99 + where they are native Windows paths. *) 94 100 Printf.sprintf " -fdebug-prefix-map=%s=%s" name stable 95 101 | Some _ | None -> "" in 96 102 let exit =
+1
utils/clflags.ml
··· 48 48 and output_name = ref (None : string option) (* -o *) 49 49 and include_dirs = ref ([] : string list) (* -I *) 50 50 and hidden_include_dirs = ref ([] : string list) (* -H *) 51 + and standard_library_default = ref None (* -set-runtime-default *) 51 52 and no_std_include = ref false (* -nostdlib *) 52 53 and no_cwd = ref false (* -nocwd *) 53 54 and print_types = ref false (* -i *)
+1
utils/clflags.mli
··· 76 76 val output_name : string option ref 77 77 val include_dirs : string list ref 78 78 val hidden_include_dirs : string list ref 79 + val standard_library_default : string option ref 79 80 val no_std_include : bool ref 80 81 val no_cwd : bool ref 81 82 val print_types : bool ref
+31 -4
utils/config.common.ml.in
··· 20 20 (* The main OCaml version string has moved to ../build-aux/ocaml_version.m4 *) 21 21 let version = Sys.ocaml_version 22 22 23 + external standard_library_default : unit -> string = "%standard_library_default" 24 + 25 + let standard_library_default_raw = standard_library_default () 26 + 27 + external stdlib_dirs : string -> string * string option 28 + = "caml_sys_get_stdlib_dirs" 29 + 30 + let standard_library_default, relative_root_dir = 31 + stdlib_dirs standard_library_default_raw 32 + 33 + let standard_library_relative = 34 + if relative_root_dir = None then 35 + None 36 + else 37 + Some standard_library_default_raw 38 + 23 39 let standard_library = 24 40 try 25 41 Sys.getenv "OCAMLLIB" ··· 28 44 Sys.getenv "CAMLLIB" 29 45 with Not_found -> 30 46 standard_library_default 47 + 48 + let bindir = Option.value ~default:bindir relative_root_dir 31 49 32 50 let exec_magic_number = {magic|@EXEC_MAGIC_NUMBER@|magic} 33 51 (* exec_magic_number is duplicated in runtime/caml/exec.h *) ··· 57 75 let max_young_wosize = 256 58 76 let stack_threshold = 32 (* see runtime/caml/config.h *) 59 77 let stack_safety_margin = 6 78 + let target_unix = (target_os_type = "Unix") 79 + let target_win32 = (target_os_type = "Win32") 80 + let target_cygwin = (target_os_type = "Cygwin") 60 81 let default_executable_name = 61 - match target_os_type with 62 - "Unix" -> "a.out" 63 - | "Win32" | "Cygwin" -> "camlprog.exe" 64 - | _ -> "camlprog" 82 + if target_unix then 83 + "a.out" 84 + else if target_win32 || target_cygwin then 85 + "camlprog.exe" 86 + else 87 + "camlprog" 65 88 type configuration_value = 66 89 | String of string 67 90 | Int of int ··· 71 94 let p x v = (x, String v) in 72 95 let p_int x v = (x, Int v) in 73 96 let p_bool x v = (x, Bool v) in 97 + let standard_library_relative = 98 + Option.value ~default:"" standard_library_relative 99 + in 74 100 [ 75 101 p "version" version; 76 102 p "standard_library_default" standard_library_default; 103 + p "standard_library_relative" standard_library_relative; 77 104 p "standard_library" standard_library; 78 105 p "ccomp_type" ccomp_type; 79 106 p "c_compiler" c_compiler;
+1 -1
utils/config.fixed.ml
··· 21 21 let boot_cannot_call s = "/ The boot compiler should not call " ^ s 22 22 23 23 let bindir = "/tmp" 24 - let standard_library_default = "/tmp" 25 24 let ccomp_type = "n/a" 26 25 let c_compiler = boot_cannot_call "the C compiler" 27 26 let c_compiler_vendor = "" 28 27 let c_output_obj = "" 29 28 let c_has_debug_prefix_map = false 30 29 let as_has_debug_prefix_map = false 30 + let as_is_cc = false 31 31 let bytecode_cflags = "" 32 32 let bytecode_cppflags = "" 33 33 let native_cflags = ""
+1 -2
utils/config.generated.ml.in
··· 20 20 21 21 let bindir = {@QS@|@ocaml_bindir@|@QS@} 22 22 23 - let standard_library_default = {@QS@|@ocaml_libdir@|@QS@} 24 - 25 23 let ccomp_type = {@QS@|@ccomp_type@|@QS@} 26 24 let c_compiler = {@QS@|@CC@|@QS@} 27 25 let c_compiler_vendor = {@QS@|@ocaml_cc_vendor@|@QS@} 28 26 let c_output_obj = {@QS@|@outputobj@|@QS@} 29 27 let c_has_debug_prefix_map = @cc_has_debug_prefix_map@ 30 28 let as_has_debug_prefix_map = @as_has_debug_prefix_map@ 29 + let as_is_cc = @as_is_cc@ 31 30 let bytecode_cflags = {@QS@|@bytecode_cflags@|@QS@} 32 31 let bytecode_cppflags = {@QS@|@bytecode_cppflags@|@QS@} 33 32 let native_cflags = {@QS@|@native_cflags@|@QS@}
+39 -4
utils/config.mli
··· 24 24 (** The current version number of the system *) 25 25 26 26 val bindir: string 27 - (** The directory containing the binary programs *) 27 + (** The directory containing the binary programs. If the compiler was configured 28 + with [--with-relative-libdir] then this will be the directory containing the 29 + currently executing runtime. *) 30 + 31 + val standard_library_relative: string option 32 + (** The explicit relative path from the compiler binaries to the standard 33 + libraries directory if the compiler was configured with 34 + [--with-relative-libdir], or [None] otherwise. 35 + 36 + @since 5.5 *) 28 37 29 38 val standard_library_default: string 30 - (** The configured value for the directory containing the standard libraries 39 + (** The effective value for the default directory containing the standard 40 + libraries. This is always an absolute path, computed using 41 + {!standard_library_relative} if necessary. 31 42 32 43 @since 5.5 *) 33 44 34 45 val standard_library: string 35 - (** The effective directory containing the standard libraries *) 46 + (** The effective directory containing the standard libraries, taking CAMLLIB 47 + and OCAMLLIB into account. *) 36 48 37 49 val ccomp_type: string 38 50 (** The "kind" of the C compiler, assembler and linker used: one of ··· 74 86 75 87 val as_has_debug_prefix_map : bool 76 88 (** Whether the assembler supports --debug-prefix-map *) 89 + 90 + val as_is_cc : bool 91 + (** Whether the assembler is actually an assembler, or whether we are really 92 + assembling files via the C compiler 93 + 94 + @since 5.5 *) 77 95 78 96 val bytecode_cflags : string 79 97 (** The flags ocamlc should pass to the C compiler *) ··· 207 225 (** Operating system targeted by the native-code compiler. One of 208 226 - ["Unix"] (for all Unix versions, including Linux and macOS), 209 227 - ["Win32"] (for MS-Windows, OCaml compiled with MSVC++ or MinGW-w64), 210 - - ["Cygwin"] (for MS-Windows, OCaml compiled with Cygwin). *) 228 + - ["Cygwin"] (for MS-Windows, OCaml compiled with Cygwin). 229 + 230 + @since 5.4 *) 231 + 232 + val target_unix: bool 233 + (** True if [target_os_type = "Unix"] 234 + 235 + @since 5.5 *) 236 + 237 + val target_win32: bool 238 + (** True if [target_os_type = "Win32"] 239 + 240 + @since 5.5 *) 241 + 242 + val target_cygwin: bool 243 + (** True if [target_os_type = "Cygwin"] 244 + 245 + @since 5.5 *) 211 246 212 247 val asm: string 213 248 (** The assembler (and flags) to use for assembling