From f4889ff63f6d5f40b2039d0303f33ce4e959d7af Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 10:45:33 +0100 Subject: [PATCH 01/92] Add -Wl,--start-group & -Wl,--end-group It's probably a better way to add libraries when we link objects from OCaml. With these options, we allow the linker to resolve all symbols regardless the order of these libraries. Indeed, the linker will repeatly lookup on these libraries until all symbols are resolved. However, it seems that these options can have an impact about performances of the linker. If we need to improve this situation, we must recalculate a topological order of libraries. But for our purpose, that's probably fine. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c439fe0c..84e07b82 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ LOCAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(TOP)/nolibc/include -include _solo5/override # CFLAGS used by the OCaml compiler to build C stubs GLOBAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(MAKECONF_PREFIX)/solo5-sysroot/include/nolibc/ -include _solo5/overrides.h # LIBS used by the OCaml compiler to link executables -GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS) +GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -Wl,--start-group -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS) -Wl,--end-group # NOLIBC NOLIBC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include @@ -45,7 +45,7 @@ ocaml/Makefile: # configure link test # - We override OCAML_OS_TYPE since configure just hardcodes it to "Unix". OC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src -nostdlib -OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) +OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -Wl,--start-group -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) -Wl,--end-group ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a # configure: Do not build dynlink sed -i -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure From 1cc70f5d2dac68c9a8eb20f8150469f7c5c53976 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 11:32:31 +0100 Subject: [PATCH 02/92] Delete the usage of `sed -i` (and replace it by `sed && mv`) `sed -i` is not POSIX, it's better to generate a `*.sed` file and move it to the real destination. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 84e07b82..582ca138 100644 --- a/Makefile +++ b/Makefile @@ -48,22 +48,32 @@ OC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src -nostd OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -Wl,--start-group -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) -Wl,--end-group ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a # configure: Do not build dynlink - sed -i -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure + sed -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure > ocaml/configure.sed && \ + mv ocaml/configure.sed ocaml/configure # configure: Allow precise input of flags and libs - sed -i -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure - sed -i -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure - sed -i -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure + sed -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \ + mv ocaml/configure.sed ocaml/configure + sed -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \ + mv ocaml/configure.sed ocaml/configure + sed -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \ + mv ocaml/configure.sed ocaml/configure + chmod +x ocaml/configure # runtime/Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system - sed -i -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile - sed -i -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/runtime/Makefile - sed -i -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/runtime/Makefile - sed -i -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile + sed -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ + mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile + sed -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ + mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile + sed -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ + mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile + sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ + mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/runtime/libcamlruni.a # yacc/Makefile: import ocamlyacc from the system - sed -i -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile + sed -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile > ocaml/yacc/Makefile.sed && \ + mv ocaml/yacc/Makefile.sed ocaml/yacc/Makefile echo -e "ocamlyacc:\n\tcp $(shell which ocamlyacc) .\n" >> ocaml/yacc/Makefile # tools/Makefile: stub out objinfo_helper echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile From 83621548467a90146db6d917c77996951c607290 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 11:36:40 +0100 Subject: [PATCH 03/92] Specify the architecture into the OCaml's `./configure` script Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 582ca138..2f287a8b 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,8 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a mv ocaml/configure.sed ocaml/configure sed -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \ mv ocaml/configure.sed ocaml/configure + sed -e 's/^arch=none$$/arch=$(MAKECONF_OCAML_BUILD_ARCH)/' ocaml/configure > ocaml/configure.sed && \ + mv ocaml/configure.sed ocaml/configure chmod +x ocaml/configure # runtime/Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system sed -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ @@ -103,7 +105,6 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a -disable-ocamltest\ -disable-ocamldoc\ $(MAKECONF_OCAML_CONFIGURE_OPTIONS) - echo "ARCH=$(MAKECONF_OCAML_BUILD_ARCH)" >> ocaml/Makefile.config echo 'SAK_CC=cc' >> ocaml/Makefile.config echo 'SAK_CFLAGS=' >> ocaml/Makefile.config echo 'SAK_LINK=cc $(SAK_CFLAGS) $$(OUTPUTEXE)$$(1) $$(2)' >> ocaml/Makefile.config From 1b2c8435e5a867d92e4f25a0bd2a0c9dbb01e180 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 11:38:14 +0100 Subject: [PATCH 04/92] Add $$PTHREAD_LIB into our pattern to modify nativecclibs With OCaml 5, the pattern was updated and has $$PTHREAD_LIB. We update accordingly. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2f287a8b..69f96915 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a mv ocaml/configure.sed ocaml/configure sed -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \ mv ocaml/configure.sed ocaml/configure - sed -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \ + sed -e 's/nativecclibs="$$cclibs $$DLLIBS $$PTHREAD_LIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \ mv ocaml/configure.sed ocaml/configure sed -e 's/^arch=none$$/arch=$(MAKECONF_OCAML_BUILD_ARCH)/' ocaml/configure > ocaml/configure.sed && \ mv ocaml/configure.sed ocaml/configure From ce907abf1c70e4410e5e4ca6690457ff9e7c731f Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 11:41:36 +0100 Subject: [PATCH 05/92] Add runtime/primitives as a dependency for the coldstart rule Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 69f96915..dc4a7d3b 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,8 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile + sed -e 's,^coldstart: $(COLDSTART_DEPS)$$,coldstart: runtime/primitives $$(COLDSTART_DEPS),' ocaml/Makefile > ocaml/Makefile.sed && \ + mv ocaml/Makefile.sed ocaml/Makefile echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile From 6608b7113f93e7cd3861631781fb6fd7f07f9224 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:31:14 +0100 Subject: [PATCH 06/92] ocamlrun{,d,i} are located into the runtime directory Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index dc4a7d3b..cf9d2e67 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,9 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile + echo -e "runtime/ocamlrun\$$(EXE):\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile + echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile + echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/runtime/libcamlruni.a # yacc/Makefile: import ocamlyacc from the system sed -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile > ocaml/yacc/Makefile.sed && \ From ed0de9c24b9aa130aa6e92aaee596c28f2de80f9 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:31:58 +0100 Subject: [PATCH 07/92] Delete fake libcamlrun{,d,i}.a from the Makefile Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index cf9d2e67..2a319e25 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,6 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a echo -e "runtime/ocamlrun\$$(EXE):\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile - touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/runtime/libcamlruni.a # yacc/Makefile: import ocamlyacc from the system sed -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile > ocaml/yacc/Makefile.sed && \ mv ocaml/yacc/Makefile.sed ocaml/yacc/Makefile From 9c2f41c2c6ac21b7fe7007c03f0740b8ab4c7792 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 13:12:48 +0100 Subject: [PATCH 08/92] /runtime/Makefile was deleted (OCaml 5.0) and everything is into /Makefile Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 2a319e25..4f0dfd1c 100644 --- a/Makefile +++ b/Makefile @@ -60,20 +60,18 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a sed -e 's/^arch=none$$/arch=$(MAKECONF_OCAML_BUILD_ARCH)/' ocaml/configure > ocaml/configure.sed && \ mv ocaml/configure.sed ocaml/configure chmod +x ocaml/configure -# runtime/Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system - sed -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ - mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile - sed -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ - mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile - sed -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ - mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile - sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile > ocaml/runtime/Makefile.sed && \ - mv ocaml/runtime/Makefile.sed ocaml/runtime/Makefile +# Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system + sed -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/Makefile > ocaml/Makefile.sed && \ + mv ocaml/Makefile.sed ocaml/Makefile + sed -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/Makefile > ocaml/Makefile.sed && \ + mv ocaml/Makefile.sed ocaml/Makefile + sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/Makefile > ocaml/Makefile.sed && \ + mv ocaml/Makefile.sed ocaml/Makefile sed -e 's,^coldstart: $(COLDSTART_DEPS)$$,coldstart: runtime/primitives $$(COLDSTART_DEPS),' ocaml/Makefile > ocaml/Makefile.sed && \ mv ocaml/Makefile.sed ocaml/Makefile - echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile - echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile - echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile + echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/Makefile + echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/Makefile + echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/Makefile echo -e "runtime/ocamlrun\$$(EXE):\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile From de5d46327eb6b69545f9e55d2e7d7c36c39a1913 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:33:39 +0100 Subject: [PATCH 09/92] Replace ocamlyacc by $$(ocamlyacc_PROGRAM) Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4f0dfd1c..413e6d88 100644 --- a/Makefile +++ b/Makefile @@ -76,9 +76,9 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile # yacc/Makefile: import ocamlyacc from the system - sed -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile > ocaml/yacc/Makefile.sed && \ - mv ocaml/yacc/Makefile.sed ocaml/yacc/Makefile - echo -e "ocamlyacc:\n\tcp $(shell which ocamlyacc) .\n" >> ocaml/yacc/Makefile + sed -e 's,^$$(ocamlyacc_PROGRAM)$$(EXE):.*,dummy_yacc:,g' ocaml/Makefile > ocaml/Makefile.sed && \ + mv ocaml/Makefile.sed ocaml/Makefile + echo -e "\$$(ocamlyacc_PROGRAM)\$$(EXE):\n\tcp $(shell which ocamlyacc) yacc/\n" >> ocaml/Makefile # tools/Makefile: stub out objinfo_helper echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile # av_cv_libm_cos=no is passed to configure to prevent -lm being used (which From 56b290cc7a811f397a5ff83749650ba01dd073ba Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:34:57 +0100 Subject: [PATCH 10/92] Replace the number of domains into our OCaml runtime Currently, OCaml 5.0 wants to create 128 domains which requires a big allocation. We decided to allow the usage of only 1 domain. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 413e6d88..906724fd 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,9 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a sed -e 's,^$$(ocamlyacc_PROGRAM)$$(EXE):.*,dummy_yacc:,g' ocaml/Makefile > ocaml/Makefile.sed && \ mv ocaml/Makefile.sed ocaml/Makefile echo -e "\$$(ocamlyacc_PROGRAM)\$$(EXE):\n\tcp $(shell which ocamlyacc) yacc/\n" >> ocaml/Makefile +# patch ocaml 5.0.0 runtime for single domain/thread solo5 + sed -e 's/#define Max_domains 128/#define Max_domains 1/' ocaml/runtime/caml/domain.h > ocaml/runtime/caml/domain.h.sed && \ + mv ocaml/runtime/caml/domain.h.sed ocaml/runtime/caml/domain.h # tools/Makefile: stub out objinfo_helper echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile # av_cv_libm_cos=no is passed to configure to prevent -lm being used (which From 4da6450ac883101ac7dae235503796f75aaa6637 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:37:11 +0100 Subject: [PATCH 11/92] Disable debug runtime Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 906724fd..8457159f 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,7 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a -disable-systhreads\ -disable-unix-lib\ -disable-instrumented-runtime\ + -disable-debug-runtime\ -disable-ocamltest\ -disable-ocamldoc\ $(MAKECONF_OCAML_CONFIGURE_OPTIONS) From 538f85ded6cb9ce5b3da6eef0439a476f07f8d19 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 13:22:26 +0100 Subject: [PATCH 12/92] Delete unecessary tweak Makefile rule about objinfo_helper Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 8457159f..89c5b283 100644 --- a/Makefile +++ b/Makefile @@ -82,8 +82,6 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a # patch ocaml 5.0.0 runtime for single domain/thread solo5 sed -e 's/#define Max_domains 128/#define Max_domains 1/' ocaml/runtime/caml/domain.h > ocaml/runtime/caml/domain.h.sed && \ mv ocaml/runtime/caml/domain.h.sed ocaml/runtime/caml/domain.h -# tools/Makefile: stub out objinfo_helper - echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile # av_cv_libm_cos=no is passed to configure to prevent -lm being used (which # would use the host system libm instead of the freestanding openlibm, see # https://github.com/mirage/ocaml-solo5/issues/101 From 1b0805cf562b5ed0769988364a00f6899e22b58f Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:38:20 +0100 Subject: [PATCH 13/92] Add a missing / into our nolibc's test-include/%.c rule Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nolibc/Makefile b/nolibc/Makefile index 4294f2cf..4dd36d45 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -42,15 +42,15 @@ TEST_H_OBJS=$(patsubst %.h,test-%.o,$(HEADERS)) # For each HEADER we want to test, generate a C source file including only # that HEADER. As above, HEADER may include subdirectories. -test-include/%.c: include/%.h | test-include/sys +test-include/%.c: include/%.h | test-include/sys/ echo "#include \"../$<\"" >$@ .PRECIOUS: test-include/%.c -test-include: +test-include/: mkdir $@ -test-include/sys: test-include +test-include/sys/: test-include/ mkdir $@ test-headers: $(TEST_H_OBJS) From 10e754d7f8fc785449b26bfc86f1de800228ff33 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:39:25 +0100 Subject: [PATCH 14/92] Add the -p option when we use mkdir (nolibc's Makefile) Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nolibc/Makefile b/nolibc/Makefile index 4dd36d45..0d262393 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -48,9 +48,9 @@ test-include/%.c: include/%.h | test-include/sys/ .PRECIOUS: test-include/%.c test-include/: - mkdir $@ + mkdir -p $@ test-include/sys/: test-include/ - mkdir $@ + mkdir -p $@ test-headers: $(TEST_H_OBJS) From c43b971d62e62703d27f7bc24f23ba9d756d2281 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 13:40:43 +0100 Subject: [PATCH 15/92] Set NATIVE_COMPILER to true into the OCaml's Makefile.config Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 89c5b283..dac400f8 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,7 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a -disable-ocamltest\ -disable-ocamldoc\ $(MAKECONF_OCAML_CONFIGURE_OPTIONS) + echo 'NATIVE_COMPILER=true' >> ocaml/Makefile.config echo 'SAK_CC=cc' >> ocaml/Makefile.config echo 'SAK_CFLAGS=' >> ocaml/Makefile.config echo 'SAK_LINK=cc $(SAK_CFLAGS) $$(OUTPUTEXE)$$(1) $$(2)' >> ocaml/Makefile.config From 4789bb526c364f8d91fa4c4f66bac057670c9285 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:11:59 +0100 Subject: [PATCH 16/92] Add test-include/sys/ as a dependency for test-headers (nolibc's Makefile) Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nolibc/Makefile b/nolibc/Makefile index 0d262393..cbeb5d78 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -53,4 +53,4 @@ test-include/: test-include/sys/: test-include/ mkdir -p $@ -test-headers: $(TEST_H_OBJS) +test-headers: test-include/sys/ $(TEST_H_OBJS) From f14407715329f7c1426e983f650e4cc2c614da84 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:18:13 +0100 Subject: [PATCH 17/92] Define EBUSY Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/errno.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index 67c3b760..fedbe481 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -10,5 +10,9 @@ extern int errno; #define EINVAL 6 #define ENOMEM 7 #define EMFILE 8 +#define EBUSY 9 +/* TODO(dinosaure): we probably should follow the Cosmopolitan + * project about these constants and use values where we have + * an {unix,bsd} consensus. */ #endif From 1043ac40d44dbaba8b994729efc7ffa9a7a10fc9 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:19:29 +0100 Subject: [PATCH 18/92] Define O_RDWR Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/fcntl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nolibc/include/fcntl.h b/nolibc/include/fcntl.h index a291d292..fd45d996 100644 --- a/nolibc/include/fcntl.h +++ b/nolibc/include/fcntl.h @@ -9,5 +9,9 @@ int open(const char *, int, ...); #define O_CREAT (1<<3) #define O_TRUNC (1<<4) #define O_EXCL (1<<5) +#define O_RDWR (1<<6) +/* TODO(dinosaure): same as errno values, we should take a + * look on the Cosmopolitan project and set values when + * we can find an {unix,bsd} consensus. */ #endif From 32be0829c4108ed4361f64fd363e8b637c7364eb Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:28:32 +0100 Subject: [PATCH 19/92] Define SIG_BLOCK/SIG_SETMASK Initially, we used NULL and it seems that these values are used by GMP. We probably break something here if NULL <> 0 but conventionally, NULL = 0. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/signal.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nolibc/include/signal.h b/nolibc/include/signal.h index 53fa89f3..f5479046 100644 --- a/nolibc/include/signal.h +++ b/nolibc/include/signal.h @@ -4,12 +4,19 @@ typedef int jmp_buf; int setjmp(jmp_buf); void (*signal(int sig, void (*func)(int)))(int); -#define SIG_DFL NULL -#define SIG_IGN NULL -#define SIG_ERR NULL +#define SIG_DFL 0 +#define SIG_IGN 0 +#define SIG_ERR 0 +#define SIG_BLOCK 0 +#define SIG_SETMASK 0 /* * The following definitions are not required by the OCaml runtime, but are * needed to build the freestanding version of GMP used by Mirage. + * For OCaml 5.0.0, it's not totally true. SIG_{BLOCK,SETMASK,IGN,DFL) are + * needed by the OCaml runtime. + * + * NOTE: Solo5 does not implement signals, but we should not trigger + * a situation where these values are really used. */ #define SIGFPE 1 int raise(int); From 8fdcbe4c1b4a1e8cb264cb89b3f21274415a656f Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 14:08:22 +0100 Subject: [PATCH 20/92] Define S_{IR,IW}USR Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/sys/stat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nolibc/include/sys/stat.h b/nolibc/include/sys/stat.h index 3f0ddffb..ab9b00b5 100644 --- a/nolibc/include/sys/stat.h +++ b/nolibc/include/sys/stat.h @@ -11,6 +11,8 @@ struct stat { #define S_IFMT 0 #define S_IFREG 0 #define S_ISREG(x) (0) +#define S_IRUSR 0 +#define S_IWUSR 0 int stat(const char *, struct stat *); int mkdir(const char *, mode_t); From 2988ad0857bf4d256038215d8a22c97e3661cdce Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:20:24 +0100 Subject: [PATCH 21/92] Stub pthread Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/pthread.h | 57 ++++++++++++++++++++++++++++++++++++++++ nolibc/stubs.c | 42 +++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 nolibc/include/pthread.h diff --git a/nolibc/include/pthread.h b/nolibc/include/pthread.h new file mode 100644 index 00000000..ea7b5651 --- /dev/null +++ b/nolibc/include/pthread.h @@ -0,0 +1,57 @@ +#ifndef _PTHREAD_H +#define _PTHREAD_H + +#include +#include + +typedef unsigned long int pthread_t; +typedef int cpu_set_t; + +int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *); + +pthread_t pthread_self(void); + +typedef int pthread_attr_t; + +int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); +int pthread_join(pthread_t, void **); +int pthread_attr_init(pthread_attr_t *); +void pthread_cleanup_push(void (*)(void *), void *); +void pthread_cleanup_pop(int); + +typedef int pthread_mutex_t; +typedef int pthread_cond_t; + +int pthread_mutex_lock(pthread_mutex_t *); +int pthread_mutex_trylock(pthread_mutex_t *); +int pthread_mutex_unlock(pthread_mutex_t *); + +#define PTHREAD_MUTEX_INITIALIZER 0 +#define PTHREAD_COND_INITIALIZER 0 + +int pthread_sigmask(int, const sigset_t *, sigset_t *); +int pthread_detach(pthread_t); +int pthread_equal(pthread_t, pthread_t); + +typedef int pthread_mutexattr_t; + +int pthread_mutexattr_init(pthread_mutexattr_t *); +int pthread_mutexattr_settype(pthread_mutexattr_t *, int); + +#define PTHREAD_MUTEX_ERRORCHECK 0 + +int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); +int pthread_mutexattr_destroy(pthread_mutexattr_t *); +int pthread_mutex_destroy(pthread_mutex_t *); + +typedef int pthread_condattr_t; + +int pthread_condattr_init(pthread_condattr_t *); +int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); + +int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); +int pthread_cond_broadcast(pthread_cond_t *); +int pthread_cond_signal(pthread_cond_t *); +int pthread_cond_destroy(pthread_cond_t *); + +#endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 5f951b0a..e444f2a5 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -100,3 +100,45 @@ STUB_ABORT(strerror); /* sys/stat.h */ STUB_WARN_ONCE(int, stat, -1); STUB_ABORT(mkdir); + +/* pthread.h */ +STUB_IGNORE(int, pthread_join, 0); +STUB_IGNORE(int, pthread_create, 0); +STUB_IGNORE(int, pthread_attr_init, 0); +STUB_ABORT(pthread_cleanup_push); +STUB_ABORT(pthread_cleanup_pop); + +STUB_IGNORE(int, munmap, 0); /* TODO: Implement munmap correctly and avoid memory leaks */ + +int memory_order_release; +int memory_order_acquire; +int memory_order_relaxed; + +STUB_ABORT(atomic_store_explicit); +STUB_ABORT(atomic_exchange); + +/* above that line, for OCaml 5, those are only required (i guess) for the configure step */ +STUB_IGNORE(int, pthread_mutex_lock, 0); +STUB_IGNORE(int, pthread_mutex_trylock, 0); +STUB_IGNORE(int, pthread_mutex_unlock, 0); +STUB_IGNORE(int, pthread_mutex_destroy, 0); +STUB_IGNORE(int, pthread_mutex_init, 0); + +STUB_IGNORE(int, pthread_mutexattr_init, 0); +STUB_IGNORE(int, pthread_mutexattr_destroy, 0); +STUB_IGNORE(int, pthread_mutexattr_settype, 0); + +STUB_IGNORE(int, pthread_sigmask, 0); + +STUB_IGNORE(int, pthread_equal, 1); + +STUB_IGNORE(int, pthread_condattr_init, 0); +/* TODO: Is there a memory leak in OCaml? Shouldn't there be a call to pthread_condattr_destroy? */ + +STUB_IGNORE(int, pthread_cond_init, 0); +STUB_ABORT(pthread_cond_destroy); +STUB_ABORT(pthread_cond_wait); +STUB_ABORT(pthread_cond_signal); +STUB_IGNORE(int, pthread_cond_broadcast, 0); +STUB_ABORT(pthread_self); +STUB_ABORT(pthread_detach); From 073292a1355d418c67e965bd3f5ce3d05d917343 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:30:52 +0100 Subject: [PATCH 22/92] Stub sigfillset Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/signal.h | 3 +++ nolibc/stubs.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/nolibc/include/signal.h b/nolibc/include/signal.h index f5479046..5d0a9d55 100644 --- a/nolibc/include/signal.h +++ b/nolibc/include/signal.h @@ -21,4 +21,7 @@ void (*signal(int sig, void (*func)(int)))(int); #define SIGFPE 1 int raise(int); +typedef int sigset_t; +int sigfillset(sigset_t *); + #endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index e444f2a5..c20451a4 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -142,3 +142,5 @@ STUB_ABORT(pthread_cond_signal); STUB_IGNORE(int, pthread_cond_broadcast, 0); STUB_ABORT(pthread_self); STUB_ABORT(pthread_detach); + +STUB_ABORT(sigfillset); From 7ee377efe5b7f6549645b33859e1442d7ce1c59c Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Fri, 13 Jan 2023 12:27:02 +0100 Subject: [PATCH 23/92] Stub fputs, fopen and fclose and implement puts and putchar As usual, we stub fputs, fopen and fclose which manipulate file description (and they don't exist with Solo5). However, puts and putchar use stdout and we decided to implement them (they will write _via_ Solo5 into stderr). Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 2 +- nolibc/assert.c | 8 +------- nolibc/include/stdio.h | 5 +++++ nolibc/puts.c | 17 +++++++++++++++++ nolibc/stubs.c | 3 +++ 5 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 nolibc/puts.c diff --git a/nolibc/Makefile b/nolibc/Makefile index cbeb5d78..571add12 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -21,7 +21,7 @@ OBJS=assert.o \ dtoa.o \ memchr.o memcmp.o memcpy.o memmove.o memset.o \ strcmp.o strlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \ - strstr.o strncmp.o \ + strstr.o strncmp.o puts.o \ stubs.o \ vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o diff --git a/nolibc/assert.c b/nolibc/assert.c index dcdcd1fc..ae89be31 100644 --- a/nolibc/assert.c +++ b/nolibc/assert.c @@ -1,17 +1,11 @@ #include -#include -#include +#include /* * These functions deliberately do not call printf() or malloc() in order to * abort as quickly as possible without triggering further errors. */ -static void puts(const char *s) -{ - (void)write(2, s, strlen(s)); -} - void _assert_fail(const char *file, const char *line, const char *e) { puts(file); diff --git a/nolibc/include/stdio.h b/nolibc/include/stdio.h index 43b959e0..0754a18e 100644 --- a/nolibc/include/stdio.h +++ b/nolibc/include/stdio.h @@ -33,5 +33,10 @@ size_t fwrite(const void *, size_t, size_t, FILE *); int fputc(int, FILE *); int putc(int, FILE *); int ferror(FILE *); +int fputs(const char *, FILE *); +FILE *fopen(const char *, const char *); +int fclose(FILE *); +int puts(const char *); +int putchar(int); #endif diff --git a/nolibc/puts.c b/nolibc/puts.c new file mode 100644 index 00000000..a8c366a0 --- /dev/null +++ b/nolibc/puts.c @@ -0,0 +1,17 @@ +#include +#include + +extern void solo5_console_write(const char *, size_t); + +int puts(const char *s) +{ + size_t len = strlen(s); + solo5_console_write(s, len); + return (len); +} + +int putchar(int chr) +{ + solo5_console_write((char *) &chr, 1); + return (1); +} diff --git a/nolibc/stubs.c b/nolibc/stubs.c index c20451a4..4ae7260b 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -55,8 +55,11 @@ STUB_WARN_ONCE(int, getc, EOF); STUB_WARN_ONCE(int, ungetc, EOF); STUB_WARN_ONCE(int, fwrite, 0); STUB_WARN_ONCE(int, fputc, EOF); +STUB_WARN_ONCE(int, fputs, EOF); STUB_WARN_ONCE(int, putc, EOF); STUB_WARN_ONCE(int, ferror, 1); +STUB_WARN_ONCE(int, fopen, 1); +STUB_WARN_ONCE(int, fclose, 1); /* stdlib.h */ STUB_WARN_ONCE(char *, getenv, NULL); From cc4f67876c8a1221a48fa8c5c5a786839c37f3f1 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 14:01:15 +0100 Subject: [PATCH 24/92] Stub strerror_r Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/string.h | 4 ++++ nolibc/stubs.c | 1 + 2 files changed, 5 insertions(+) diff --git a/nolibc/include/string.h b/nolibc/include/string.h index 10fb3619..9f16cb47 100644 --- a/nolibc/include/string.h +++ b/nolibc/include/string.h @@ -23,4 +23,8 @@ char *strstr(const char *, const char *); */ int strncmp(const char*, const char*, size_t); +/* TODO(dinosaure): we must track where they are used to know if we need + * to implement them or not. */ +int strerror_r(int errnum, char *buf, size_t buflen); + #endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 4ae7260b..8c4bc1b4 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -147,3 +147,4 @@ STUB_ABORT(pthread_self); STUB_ABORT(pthread_detach); STUB_ABORT(sigfillset); +STUB_ABORT(strerror_r); From d3375f1295f5a8f4fcce2921eb3eb2502c7f600a Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 12:34:43 +0100 Subject: [PATCH 25/92] Stub ftruncate Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/unistd.h | 1 + nolibc/stubs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/nolibc/include/unistd.h b/nolibc/include/unistd.h index 479e6fcf..8240ba65 100644 --- a/nolibc/include/unistd.h +++ b/nolibc/include/unistd.h @@ -15,5 +15,6 @@ ssize_t write(int, const void *, size_t); ssize_t readlink(const char *, char *, size_t); int unlink(const char *); int rmdir(const char *); +int ftruncate(int, off_t); #endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 8c4bc1b4..0402e532 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -78,6 +78,7 @@ STUB_ABORT(read); STUB_IGNORE(int, readlink, -1); STUB_ABORT(unlink); STUB_ABORT(rmdir); +STUB_ABORT(ftruncate); /* dirent.h */ STUB_WARN_ONCE(int, closedir, -1); From 951c5155474a087aaa45b471a86bb27939686f0a Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 13:54:03 +0100 Subject: [PATCH 26/92] Stub usleep Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/sys/types.h | 1 + nolibc/include/unistd.h | 1 + nolibc/stubs.c | 1 + 3 files changed, 3 insertions(+) diff --git a/nolibc/include/sys/types.h b/nolibc/include/sys/types.h index a916f597..af8bcacb 100644 --- a/nolibc/include/sys/types.h +++ b/nolibc/include/sys/types.h @@ -8,5 +8,6 @@ typedef int pid_t; typedef int off_t; typedef int ssize_t; typedef int mode_t; +typedef int useconds_t; #endif diff --git a/nolibc/include/unistd.h b/nolibc/include/unistd.h index 8240ba65..60a112fd 100644 --- a/nolibc/include/unistd.h +++ b/nolibc/include/unistd.h @@ -15,6 +15,7 @@ ssize_t write(int, const void *, size_t); ssize_t readlink(const char *, char *, size_t); int unlink(const char *); int rmdir(const char *); +int usleep(useconds_t); int ftruncate(int, off_t); #endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 0402e532..155c0e6e 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -148,4 +148,5 @@ STUB_ABORT(pthread_self); STUB_ABORT(pthread_detach); STUB_ABORT(sigfillset); +STUB_ABORT(usleep); STUB_ABORT(strerror_r); From 1fe160ebd0c1fb2d430b4da17d1f699c8eb91bdd Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 14:01:28 +0100 Subject: [PATCH 27/92] Export stdrup & strcpy Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/string.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nolibc/include/string.h b/nolibc/include/string.h index 9f16cb47..226325e5 100644 --- a/nolibc/include/string.h +++ b/nolibc/include/string.h @@ -16,6 +16,7 @@ char *strerror(int); * needed to build the freestanding version of GMP used by Mirage. */ char *strncpy(char *, const char *, size_t); +char *strcpy(char *, const char *); char *strchr(const char *, int); char *strstr(const char *, const char *); /* @@ -26,5 +27,6 @@ int strncmp(const char*, const char*, size_t); /* TODO(dinosaure): we must track where they are used to know if we need * to implement them or not. */ int strerror_r(int errnum, char *buf, size_t buflen); +char *strdup(const char *); #endif From 9016f6769b1e77b9fe6789c2b2a8d415dc6c3a26 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:57:06 +0100 Subject: [PATCH 28/92] Export qsort and mktemp Note that these functions are not stubbed but they are just exported. They are probably not needed by the OCaml runtime but needed by the way to build OCaml. Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/stdlib.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nolibc/include/stdlib.h b/nolibc/include/stdlib.h index 9f890036..e7949749 100644 --- a/nolibc/include/stdlib.h +++ b/nolibc/include/stdlib.h @@ -31,4 +31,9 @@ int system(const char *); double strtod(const char *, char **); long strtol(const char *, char **, int); +void qsort(void *base, size_t nmemb, size_t size, + int (*compare)(const void *, const void *)); + +char *mktemp(char *); + #endif From 5f85f2dc84b8563cafb72be9b67317821d8e61a5 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 14:08:40 +0100 Subject: [PATCH 29/92] Export fstat Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/sys/stat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/nolibc/include/sys/stat.h b/nolibc/include/sys/stat.h index ab9b00b5..cf4d4a59 100644 --- a/nolibc/include/sys/stat.h +++ b/nolibc/include/sys/stat.h @@ -15,5 +15,6 @@ struct stat { #define S_IWUSR 0 int stat(const char *, struct stat *); int mkdir(const char *, mode_t); +int fstat(int, struct stat *); #endif From 1963e91983d8b4492326b486b54644fab4f17110 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:13:35 +0100 Subject: [PATCH 30/92] Export islanum and tolower Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/ctype.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nolibc/include/ctype.h b/nolibc/include/ctype.h index 354a9a70..71aab003 100644 --- a/nolibc/include/ctype.h +++ b/nolibc/include/ctype.h @@ -6,5 +6,7 @@ int isdigit(int); int isprint(int); int isspace(int); int isupper(int); +int isalnum(int); +int tolower(int); #endif From ed0053830968d8fff52bf33a06db72b1e1484914 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:24:09 +0100 Subject: [PATCH 31/92] Add longjmp & setjmp Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/setjmp.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nolibc/include/setjmp.h b/nolibc/include/setjmp.h index 2e602dad..4d079b5d 100644 --- a/nolibc/include/setjmp.h +++ b/nolibc/include/setjmp.h @@ -1 +1,5 @@ #include + +void longjmp(int, int) __attribute__ ((__noreturn__)); + +#define setjmp(buf) 0 From 68db347210928dc50f9071d44f47b23fb2c44e54 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Mon, 9 Jan 2023 17:22:40 +0100 Subject: [PATCH 32/92] Add the sched.h interface (and the CPU_ZERO value) Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/sched.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 nolibc/include/sched.h diff --git a/nolibc/include/sched.h b/nolibc/include/sched.h new file mode 100644 index 00000000..e5fa9302 --- /dev/null +++ b/nolibc/include/sched.h @@ -0,0 +1,8 @@ +#ifndef _SCHED_H +#define _SCHED_H + +typedef int cpu_set_t; + +#define CPU_ZERO (x) 0 + +#endif From e2211c88e849031df819a2eeafee5baec9a200fc Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 11:41:27 +0100 Subject: [PATCH 33/92] Add the stdatomic.h Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/include/stdatomic.h | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 nolibc/include/stdatomic.h diff --git a/nolibc/include/stdatomic.h b/nolibc/include/stdatomic.h new file mode 100644 index 00000000..af6da749 --- /dev/null +++ b/nolibc/include/stdatomic.h @@ -0,0 +1,43 @@ +#ifndef _STDATOMIC_H +#define _STDATOMIC_H + +#define atomic_load_explicit(x, mode) ( *x ) +#define atomic_load(x) ( *x ) + +extern int memory_order_release; +extern int memory_order_acquire; +extern int memory_order_relaxed; +extern int memory_order_seq_cst; + +#define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; }) +#define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y) + +#define atomic_thread_fence(MO) do {} while (0) + +typedef unsigned long long atomic_uint_fast64_t; + +#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ + ({ int ret = 0; \ + if (*OBJ == *EXPECTED) { \ + *OBJ = DESIRED; \ + ret = 1; \ + } \ + ret; \ + }) + +#define atomic_exchange(OBJ, DESIRED) \ + ({ __auto_type tmp = *OBJ; \ + *OBJ = DESIRED; \ + tmp; \ + }) + +#define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0) +#define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED) + +#define atomic_fetch_or(OBJ, ARG) \ + ({ __auto_type tmp = *OBJ; \ + *OBJ = *OBJ | ARG; \ + tmp; \ + }) + +#endif From a1da18741bd55380bb0505790b5142878f424186 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Fri, 13 Jan 2023 12:48:31 +0100 Subject: [PATCH 34/92] Add sysconf.c (to let OCaml to know the _SC_PAGE{,_}SIZE) Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 3 ++- nolibc/include/unistd.h | 4 ++++ nolibc/sysconf.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 nolibc/sysconf.c diff --git a/nolibc/Makefile b/nolibc/Makefile index 571add12..24a6651c 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -23,7 +23,8 @@ OBJS=assert.o \ strcmp.o strlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \ strstr.o strncmp.o puts.o \ stubs.o \ - vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o + vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o \ + sysconf.o dtoa.o: CFLAGS+=-fno-strict-aliasing diff --git a/nolibc/include/unistd.h b/nolibc/include/unistd.h index 60a112fd..cbedb7a3 100644 --- a/nolibc/include/unistd.h +++ b/nolibc/include/unistd.h @@ -17,5 +17,9 @@ int unlink(const char *); int rmdir(const char *); int usleep(useconds_t); int ftruncate(int, off_t); +long sysconf(int); + +#define _SC_PAGESIZE 1 +#define _SC_PAGE_SIZE _SC_PAGESIZE #endif diff --git a/nolibc/sysconf.c b/nolibc/sysconf.c new file mode 100644 index 00000000..5e12bf38 --- /dev/null +++ b/nolibc/sysconf.c @@ -0,0 +1,10 @@ +#include + +long sysconf(int x) { + switch (x) { + case _SC_PAGESIZE: /* _SC_PAGE_SIZE */ + return (1 << 12); /* TODO: How do we do better? */ + default: + return -1; + } +} From 2f1a14801e5321e8b14d3d532e7b13fe4be5bae4 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Fri, 13 Jan 2023 12:49:00 +0100 Subject: [PATCH 35/92] Add the mmap() function Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/Makefile | 3 ++- nolibc/include/sys/mman.h | 25 +++++++++++++++++++++++++ nolibc/mmap.c | 35 +++++++++++++++++++++++++++++++++++ nolibc/sysconf.c | 3 ++- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 nolibc/include/sys/mman.h create mode 100644 nolibc/mmap.c diff --git a/nolibc/Makefile b/nolibc/Makefile index 24a6651c..6f8f4c3e 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -24,7 +24,8 @@ OBJS=assert.o \ strstr.o strncmp.o puts.o \ stubs.o \ vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o \ - sysconf.o + sysconf.o \ + mmap.o dtoa.o: CFLAGS+=-fno-strict-aliasing diff --git a/nolibc/include/sys/mman.h b/nolibc/include/sys/mman.h new file mode 100644 index 00000000..59bd8a2e --- /dev/null +++ b/nolibc/include/sys/mman.h @@ -0,0 +1,25 @@ +#ifndef _MMAP_H +#define _MMAP_H + +#include +#include + +void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED NULL + +#define OCAML_SOLO5_PAGESIZE (1 << 12) + +int munmap(void *addr, size_t len); + +#endif diff --git a/nolibc/mmap.c b/nolibc/mmap.c new file mode 100644 index 00000000..03ca1f96 --- /dev/null +++ b/nolibc/mmap.c @@ -0,0 +1,35 @@ +#include +#include + +#include + +void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { + + /* man page for mmap says: + * If addr is not NULL, then the kernel takes it as a hint about where to place + * the mapping; [...] If another apping already exists there, the kernel picks + * a new address that may or *may not* depend on the hint. + * + * XXX(dinosaure): for our purpose (Solo5 & OCaml), OCaml does not require a + * specific (aligned) address from [mmap]. We can use [malloc()] instead of. + * The OCaml usage of [mmap()] is only to allocate some spaces, only [fildes + * == -1] is handled so. + */ + (void)addr; + (void)prot; + if (fildes != -1) { + printf("mmap: file descriptor is unsupported.\n"); + abort(); + } + if (!(flags & MAP_ANONYMOUS) || off != 0) { + printf("mmap: only MAP_ANONYMOUS (and offset is 0) is supported.\n"); + abort(); + } + + void *ptr = NULL; + posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); + /* XXX(palainp): Solo5 returns -1 and set errno on error, and it does not + * modify ptr, however both are not standardized. We can return NULL to the + * caller on error and do not check the returned value here. */ + return ptr; +} diff --git a/nolibc/sysconf.c b/nolibc/sysconf.c index 5e12bf38..81297ec9 100644 --- a/nolibc/sysconf.c +++ b/nolibc/sysconf.c @@ -1,9 +1,10 @@ #include +#include long sysconf(int x) { switch (x) { case _SC_PAGESIZE: /* _SC_PAGE_SIZE */ - return (1 << 12); /* TODO: How do we do better? */ + return OCAML_SOLO5_PAGESIZE; default: return -1; } From 27477023f51cd76999d320b00447d362794bd2c1 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 12:12:51 +0100 Subject: [PATCH 36/92] Initialise the Thread Local Store Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- nolibc/sysdeps_solo5.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nolibc/sysdeps_solo5.c b/nolibc/sysdeps_solo5.c index dacd0215..1c308806 100644 --- a/nolibc/sysdeps_solo5.c +++ b/nolibc/sysdeps_solo5.c @@ -76,6 +76,7 @@ static uintptr_t sbrk_start; static uintptr_t sbrk_end; static uintptr_t sbrk_cur; static uintptr_t sbrk_guard_size; +static uint8_t tls[4096]; /* * To be called by Mirage/Solo5 before calling caml_startup(). @@ -96,6 +97,7 @@ void _nolibc_init(uintptr_t heap_start, size_t heap_size) sbrk_start = sbrk_cur = heap_start; sbrk_end = heap_start + heap_size; + solo5_set_tls_base((uintptr_t)tls); } /* From 64ca6aeeab3ae1ef3111905f627ba4a4c0ed161d Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 13:46:51 +0100 Subject: [PATCH 37/92] Upgrade ocaml-solo5 with OCaml 5.0 Co-authored-by: Pierre Alain Co-authored-by: Kate Co-authored-by: Christiano Haesbaert --- ocaml-solo5-cross-aarch64.opam | 2 +- ocaml-solo5.opam | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index b37d92cf..ee09df14 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -21,7 +21,7 @@ depends: [ "conf-which" {build} "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "4.12.1" & < "4.15.0"} + "ocaml" {>= "5.0" & < "5.1"} "solo5" {>= "0.7.0"} "solo5-cross-aarch64" {>= "0.7.0" } ] diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index 24450a6a..b9f6c2f6 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -22,7 +22,7 @@ depends: [ "conf-which" {build} "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "4.12.1" & < "4.15.0"} + "ocaml" {>= "5.0" & < "5.1"} "solo5" {>= "0.7.0"} ] conflicts: [ From d4ba60e67217ba28eb145e4a606571993b2cb311 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Wed, 11 Jan 2023 14:22:39 +0100 Subject: [PATCH 38/92] Upgrade GitHub workflow and Cirrus CI with OCaml 5.0 --- .cirrus.yml | 4 +--- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 369baf5a..02e0837b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,9 +6,7 @@ freebsd_task: OPAMYES: 1 env: matrix: - - OCAML_VERSION: 4.12.1 - - OCAML_VERSION: 4.13.1 - - OCAML_VERSION: 4.14.2 + - OCAML_VERSION: 5.0.0 pkg_install_script: pkg install -y ocaml-opam gmp gmake pkgconf bash opam_ocaml_cache: folder: $HOME/.opam diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 66571519..ec62310d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ jobs: test: strategy: matrix: - ocaml-compiler: ["4.12", "4.13", "4.14"] + ocaml-compiler: [5.0.0] name: OCaml ${{ matrix.ocaml-compiler }} runs-on: ubuntu-latest steps: From ee81a3b6916bc9511f011d3e5a5b2f40c126b495 Mon Sep 17 00:00:00 2001 From: Romain Calascibetta Date: Thu, 19 Jan 2023 15:24:58 +0100 Subject: [PATCH 39/92] Use __c11 atomic macros when they are available (and fix the LLVM support) Co-authored-by: Pierre Alain --- nolibc/include/stdatomic.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/nolibc/include/stdatomic.h b/nolibc/include/stdatomic.h index af6da749..6ab87ddd 100644 --- a/nolibc/include/stdatomic.h +++ b/nolibc/include/stdatomic.h @@ -1,6 +1,11 @@ #ifndef _STDATOMIC_H #define _STDATOMIC_H +// Compatibility with non-clang compilers +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + #define atomic_load_explicit(x, mode) ( *x ) #define atomic_load(x) ( *x ) @@ -9,13 +14,23 @@ extern int memory_order_acquire; extern int memory_order_relaxed; extern int memory_order_seq_cst; +#if __has_builtin(__c11_atomic_fetch_add) +#define atomic_fetch_add(X, Y) __c11_atomic_fetch_add(X, Y, __ATOMIC_SEQ_CST) +#else #define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; }) +#endif + #define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y) #define atomic_thread_fence(MO) do {} while (0) typedef unsigned long long atomic_uint_fast64_t; +#if __has_builtin(__c11_atomic_compare_exchange_strong) +#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ + __c11_atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED, \ + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) +#else #define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ ({ int ret = 0; \ if (*OBJ == *EXPECTED) { \ @@ -24,20 +39,31 @@ typedef unsigned long long atomic_uint_fast64_t; } \ ret; \ }) +#endif +#if __has_builtin(__c11_atomic_exchange) +#define atomic_exchange(OBJ, DESIRED) \ + __c11_atomic_exchange(OBJ, DESIRED, __ATOMIC_SEQ_CST) +#else #define atomic_exchange(OBJ, DESIRED) \ ({ __auto_type tmp = *OBJ; \ *OBJ = DESIRED; \ tmp; \ }) +#endif #define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0) #define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED) +#if __has_builtin(__c11_atomic_fetch_or) +#define atomic_fetch_or(OBJ, ARG) \ + __c11_atomic_fetch_or(OBJ, ARG, __ATOMIC_SEQ_CST) +#else #define atomic_fetch_or(OBJ, ARG) \ ({ __auto_type tmp = *OBJ; \ *OBJ = *OBJ | ARG; \ tmp; \ }) +#endif #endif From 573a10fb3e26f71e74554c48743b17254a253803 Mon Sep 17 00:00:00 2001 From: palainp Date: Tue, 7 Feb 2023 15:21:19 +0100 Subject: [PATCH 40/92] Update to the new Solo5 API. --- nolibc/sysdeps_solo5.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/nolibc/sysdeps_solo5.c b/nolibc/sysdeps_solo5.c index 1c308806..b98c5875 100644 --- a/nolibc/sysdeps_solo5.c +++ b/nolibc/sysdeps_solo5.c @@ -76,7 +76,7 @@ static uintptr_t sbrk_start; static uintptr_t sbrk_end; static uintptr_t sbrk_cur; static uintptr_t sbrk_guard_size; -static uint8_t tls[4096]; +static uintptr_t tls_main; /* * To be called by Mirage/Solo5 before calling caml_startup(). @@ -97,7 +97,20 @@ void _nolibc_init(uintptr_t heap_start, size_t heap_size) sbrk_start = sbrk_cur = heap_start; sbrk_end = heap_start + heap_size; - solo5_set_tls_base((uintptr_t)tls); + + tls_main = (uintptr_t)calloc(solo5_tls_size(), sizeof(uint8_t)); + if (tls_main == (uintptr_t)NULL) { + solo5_console_write("TLS alloc failed\n", 17); + abort(); + } + if (solo5_tls_init(tls_main) != SOLO5_R_OK) { + solo5_console_write("TLS init failed\n", 16); + abort(); + } + if (solo5_set_tls_base(solo5_tls_tp_offset(tls_main)) != SOLO5_R_OK) { + solo5_console_write("TLS set failed\n", 15); + abort(); + } } /* From eac32c7cbad49e5d3585ff27703d686189187325 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Fri, 19 May 2023 11:53:13 +0200 Subject: [PATCH 41/92] minor change to trigger CI --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c3b614b5..3b1726ff 100644 --- a/README.md +++ b/README.md @@ -71,8 +71,7 @@ Run: `solo5-hvt _build/solo5/main.exe` ## Supported compiler versions -Tested against OCaml 4.12.1 through 4.14.1. Other versions may require -changing `configure.sh`. +Tested against OCaml 5.0. Other versions may require changing `configure.sh`. ## Porting to a different (uni)kernel base layer From c8824a0474215b249fbff0b283f152eb2866fe0a Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:09:04 +0200 Subject: [PATCH 42/92] use linux defines constants --- nolibc/include/errno.h | 21 +++++++++------------ nolibc/include/fcntl.h | 17 +++++++---------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index fedbe481..54a52abc 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -2,17 +2,14 @@ #define _ERRNO_H extern int errno; -#define EBADF 1 -#define ERANGE 2 -#define ENOSYS 3 -#define EOVERFLOW 4 -#define ENOENT 5 -#define EINVAL 6 -#define ENOMEM 7 -#define EMFILE 8 -#define EBUSY 9 -/* TODO(dinosaure): we probably should follow the Cosmopolitan - * project about these constants and use values where we have - * an {unix,bsd} consensus. */ +#define EBADF 9 /* Bad file number */ +#define ENOENT 2 /* No such file or directory */ +#define ENOMEM 12 /* Out of memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EINVAL 22 /* Invalid argument */ +#define EMFILE 24 /* Too many open files */ +#define ERANGE 34 /* Math result not representable */ +#define ENOSYS 38 /* Invalid system call number */ +#define EOVERFLOW 75 /* Value too large for defined data type */ #endif diff --git a/nolibc/include/fcntl.h b/nolibc/include/fcntl.h index fd45d996..88c292cb 100644 --- a/nolibc/include/fcntl.h +++ b/nolibc/include/fcntl.h @@ -3,15 +3,12 @@ int fcntl(int, int, ...); int open(const char *, int, ...); -#define O_RDONLY (1<<0) -#define O_WRONLY (1<<1) -#define O_APPEND (1<<2) -#define O_CREAT (1<<3) -#define O_TRUNC (1<<4) -#define O_EXCL (1<<5) -#define O_RDWR (1<<6) -/* TODO(dinosaure): same as errno values, we should take a - * look on the Cosmopolitan project and set values when - * we can find an {unix,bsd} consensus. */ +#define O_RDONLY 00000000 +#define O_WRONLY 00000001 +#define O_RDWR 00000002 +#define O_CREAT 00000100 +#define O_EXCL 00000200 +#define O_TRUNC 00001000 +#define O_APPEND 00002000 #endif From d3225a7d463cffe781713a68213ef341ec7af09c Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:09:39 +0200 Subject: [PATCH 43/92] bump solo5 version --- ocaml-solo5-cross-aarch64.opam | 4 ++-- ocaml-solo5.opam | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index ee09df14..c6d452e7 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -22,8 +22,8 @@ depends: [ "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} "ocaml" {>= "5.0" & < "5.1"} - "solo5" {>= "0.7.0"} - "solo5-cross-aarch64" {>= "0.7.0" } + "solo5" {>= "0.8.0"} + "solo5-cross-aarch64" {>= "0.8.0" } ] conflicts: [ "ocaml-solo5" diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index b9f6c2f6..ff5c3c39 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -23,7 +23,7 @@ depends: [ "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} "ocaml" {>= "5.0" & < "5.1"} - "solo5" {>= "0.7.0"} + "solo5" {>= "0.8.0"} ] conflicts: [ "sexplib" {= "v0.9.0"} From 8d8acc347d6632135b7fcbfcfb554f05c7c51e9a Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:10:41 +0200 Subject: [PATCH 44/92] explicit conversion from size_t to int --- nolibc/puts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nolibc/puts.c b/nolibc/puts.c index a8c366a0..98a5fb81 100644 --- a/nolibc/puts.c +++ b/nolibc/puts.c @@ -7,7 +7,7 @@ int puts(const char *s) { size_t len = strlen(s); solo5_console_write(s, len); - return (len); + return (int)(len); // We should never have a string length above MAX_INT, do we? } int putchar(int chr) From cf39fcd7bc68476e7263c96854fc1661fecfe6aa Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:11:09 +0200 Subject: [PATCH 45/92] add munmap --- nolibc/mmap.c | 11 +++++++++++ nolibc/stubs.c | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/nolibc/mmap.c b/nolibc/mmap.c index 03ca1f96..cfbf5f15 100644 --- a/nolibc/mmap.c +++ b/nolibc/mmap.c @@ -33,3 +33,14 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { * caller on error and do not check the returned value here. */ return ptr; } + +int munmap(void *addr, size_t length) +{ + /* munmap man page : The address addr must be a multiple of the page size (but length need not be). */ + if (addr & OCAML_SOLO5_PAGESIZE != 0) { + return EINVAL; + } + + free(addr); + return 0; +} diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 155c0e6e..7e45ec5b 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -112,8 +112,6 @@ STUB_IGNORE(int, pthread_attr_init, 0); STUB_ABORT(pthread_cleanup_push); STUB_ABORT(pthread_cleanup_pop); -STUB_IGNORE(int, munmap, 0); /* TODO: Implement munmap correctly and avoid memory leaks */ - int memory_order_release; int memory_order_acquire; int memory_order_relaxed; @@ -137,7 +135,9 @@ STUB_IGNORE(int, pthread_sigmask, 0); STUB_IGNORE(int, pthread_equal, 1); STUB_IGNORE(int, pthread_condattr_init, 0); -/* TODO: Is there a memory leak in OCaml? Shouldn't there be a call to pthread_condattr_destroy? */ +/* pthread_condattr_destroy: not used by Ocaml 5 (pthread_condattr_init is only used in + ocaml/runtime/platform.c with a function local variable as argument) + */ STUB_IGNORE(int, pthread_cond_init, 0); STUB_ABORT(pthread_cond_destroy); From 2b447f10fa0dc59c4e08f434d45aecb0be271d48 Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:21:15 +0200 Subject: [PATCH 46/92] bump ocaml version --- ocaml-solo5-cross-aarch64.opam | 2 +- ocaml-solo5.opam | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index c6d452e7..1b589bfe 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -21,7 +21,7 @@ depends: [ "conf-which" {build} "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "5.0" & < "5.1"} + "ocaml" {>= "5.0" & < "5.2"} "solo5" {>= "0.8.0"} "solo5-cross-aarch64" {>= "0.8.0" } ] diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index ff5c3c39..480f39e5 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -22,7 +22,7 @@ depends: [ "conf-which" {build} "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "5.0" & < "5.1"} + "ocaml" {>= "5.0" & < "5.2"} "solo5" {>= "0.8.0"} ] conflicts: [ From 3910f9423c1717d423970ce86ac8ad1385b0f638 Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:26:03 +0200 Subject: [PATCH 47/92] fix mmap and munmap --- nolibc/mmap.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/nolibc/mmap.c b/nolibc/mmap.c index cfbf5f15..8ad1007b 100644 --- a/nolibc/mmap.c +++ b/nolibc/mmap.c @@ -1,22 +1,28 @@ #include #include +#include #include void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { /* man page for mmap says: - * If addr is not NULL, then the kernel takes it as a hint about where to place - * the mapping; [...] If another apping already exists there, the kernel picks - * a new address that may or *may not* depend on the hint. + * If addr is NULL, then the kernel chooses the (page-aligned) address at + * which to create the mapping; this is the most portable method of creat‐ + * ing a new mapping. If addr is not NULL, then the kernel takes it as a hint + * about where to place the mapping; [...] If another apping already exists + * there, the kernel picks a new address that may or *may not* depend on the hint. + * + * For our purpose (Solo5 & OCaml), OCaml might use a NULL addr and force us to + * use posix_memalign. If addr is not NULL we might use [malloc()] instead of. + * XXX(palainp): Does it worth to have a test on addr here? * - * XXX(dinosaure): for our purpose (Solo5 & OCaml), OCaml does not require a - * specific (aligned) address from [mmap]. We can use [malloc()] instead of. * The OCaml usage of [mmap()] is only to allocate some spaces, only [fildes * == -1] is handled so. */ - (void)addr; - (void)prot; + (void)addr; // unused argument + (void)prot; // unused argument + if (fildes != -1) { printf("mmap: file descriptor is unsupported.\n"); abort(); @@ -27,18 +33,25 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { } void *ptr = NULL; - posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); - /* XXX(palainp): Solo5 returns -1 and set errno on error, and it does not - * modify ptr, however both are not standardized. We can return NULL to the - * caller on error and do not check the returned value here. */ - return ptr; + int ret = posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); + if (ret == -1) { + /* Solo5 returns -1 and set errno on error, just return MAP_FAILED. */ + return (void*)-1; // MAP_FAILED + } else { + return ptr; + } } int munmap(void *addr, size_t length) { - /* munmap man page : The address addr must be a multiple of the page size (but length need not be). */ - if (addr & OCAML_SOLO5_PAGESIZE != 0) { - return EINVAL; + (void)length; // unused argument + + /* man page for munmap says: + * The address addr must be a multiple of the page size (but length need not be). + */ + if ((uintptr_t)addr & OCAML_SOLO5_PAGESIZE != 0) { + errno = EINVAL; + return -1; } free(addr); From b352ccec972ab32724e29e959606b9069c722788 Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Wed, 18 Oct 2023 16:47:51 +0200 Subject: [PATCH 48/92] add CHAR_BIT --- nolibc/include/limits.h | 1 + 1 file changed, 1 insertion(+) diff --git a/nolibc/include/limits.h b/nolibc/include/limits.h index c4f2b2a6..ee74def2 100644 --- a/nolibc/include/limits.h +++ b/nolibc/include/limits.h @@ -18,5 +18,6 @@ #define ULONG_MAX (2UL*LONG_MAX+1) #define NL_ARGMAX 9 #define UCHAR_MAX 255 +#define CHAR_BIT 8 #endif From 981514662b6fd435b29b25679d0edb40628acc96 Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Mon, 20 Nov 2023 18:35:14 +0100 Subject: [PATCH 49/92] relax alignment with mmap when addr is not NULL --- nolibc/include/sys/mman.h | 3 ++- nolibc/mmap.c | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/nolibc/include/sys/mman.h b/nolibc/include/sys/mman.h index 59bd8a2e..5554ebdf 100644 --- a/nolibc/include/sys/mman.h +++ b/nolibc/include/sys/mman.h @@ -16,7 +16,8 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); #define MAP_ANONYMOUS 0x20 #define MAP_ANON MAP_ANONYMOUS -#define MAP_FAILED NULL +// the MAP_FAILED comply with the mmap manual page +#define MAP_FAILED (void*)-1 #define OCAML_SOLO5_PAGESIZE (1 << 12) diff --git a/nolibc/mmap.c b/nolibc/mmap.c index 8ad1007b..209bfde3 100644 --- a/nolibc/mmap.c +++ b/nolibc/mmap.c @@ -14,13 +14,11 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { * there, the kernel picks a new address that may or *may not* depend on the hint. * * For our purpose (Solo5 & OCaml), OCaml might use a NULL addr and force us to - * use posix_memalign. If addr is not NULL we might use [malloc()] instead of. - * XXX(palainp): Does it worth to have a test on addr here? + * use posix_memalign. If addr is not NULL we can use [malloc()] instead of. * * The OCaml usage of [mmap()] is only to allocate some spaces, only [fildes * == -1] is handled so. */ - (void)addr; // unused argument (void)prot; // unused argument if (fildes != -1) { @@ -33,10 +31,21 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { } void *ptr = NULL; - int ret = posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); - if (ret == -1) { - /* Solo5 returns -1 and set errno on error, just return MAP_FAILED. */ - return (void*)-1; // MAP_FAILED + /* XXX(palainp): Does it worth to have a test on addr here? */ + if (addr == NULL) { + /* Solo5 may returns -1 and set errno on error, just return MAP_FAILED. + It doesn't modify ptr on error: ptr will still be NULL + */ + posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); + } else { + ptr = malloc(len); + if (ptr == NULL) { + errno = ENOMEM; + } + } + + if (ptr == NULL) { + return MAP_FAILED; } else { return ptr; } From ca9424c2e6a172f60ac0faa706ff87eff76b266f Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 26 Feb 2024 19:26:58 +0100 Subject: [PATCH 50/92] Stub `sigwait` --- nolibc/include/signal.h | 1 + nolibc/stubs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/nolibc/include/signal.h b/nolibc/include/signal.h index 5d0a9d55..43a00ff3 100644 --- a/nolibc/include/signal.h +++ b/nolibc/include/signal.h @@ -23,5 +23,6 @@ int raise(int); typedef int sigset_t; int sigfillset(sigset_t *); +int sigwait(const sigset_t *restrict set, int *restrict sig); #endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 7e45ec5b..161482f8 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -148,5 +148,6 @@ STUB_ABORT(pthread_self); STUB_ABORT(pthread_detach); STUB_ABORT(sigfillset); +STUB_ABORT(sigwait); STUB_ABORT(usleep); STUB_ABORT(strerror_r); From 673bc4508a0800ef304093bdc1d8c4f8c018929e Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Wed, 28 Feb 2024 14:21:41 +0100 Subject: [PATCH 51/92] Stub `execv` `execv` is used in `header.c` which will not be used in native cross-compiler anyway --- nolibc/include/unistd.h | 1 + nolibc/stubs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/nolibc/include/unistd.h b/nolibc/include/unistd.h index cbedb7a3..e3c01889 100644 --- a/nolibc/include/unistd.h +++ b/nolibc/include/unistd.h @@ -18,6 +18,7 @@ int rmdir(const char *); int usleep(useconds_t); int ftruncate(int, off_t); long sysconf(int); +int execv(const char *, char *const []); #define _SC_PAGESIZE 1 #define _SC_PAGE_SIZE _SC_PAGESIZE diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 161482f8..65a458c4 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -79,6 +79,7 @@ STUB_IGNORE(int, readlink, -1); STUB_ABORT(unlink); STUB_ABORT(rmdir); STUB_ABORT(ftruncate); +STUB_ABORT(execv); /* dirent.h */ STUB_WARN_ONCE(int, closedir, -1); From b77517a0236fc96334ba969574a7525012b3b0ca Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 27 Feb 2024 14:09:40 +0100 Subject: [PATCH 52/92] Define `static_assert` --- nolibc/include/assert.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nolibc/include/assert.h b/nolibc/include/assert.h index 2e3712bb..54fd909b 100644 --- a/nolibc/include/assert.h +++ b/nolibc/include/assert.h @@ -14,3 +14,7 @@ extern void _assert_fail(const char *, const char *, const char *) } while (0) #endif + +#ifndef static_assert +# define static_assert _Static_assert +#endif From 1f2181c5c45738ad04c30f27869684e687ff8305 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 27 Feb 2024 16:12:11 +0100 Subject: [PATCH 53/92] Define `strnlen` --- nolibc/Makefile | 2 +- nolibc/include/string.h | 1 + nolibc/strnlen.c | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 nolibc/strnlen.c diff --git a/nolibc/Makefile b/nolibc/Makefile index 6f8f4c3e..12eb5bcc 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -20,7 +20,7 @@ OBJS=assert.o \ ctype.o \ dtoa.o \ memchr.o memcmp.o memcpy.o memmove.o memset.o \ - strcmp.o strlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \ + strcmp.o strlen.o strnlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \ strstr.o strncmp.o puts.o \ stubs.o \ vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o \ diff --git a/nolibc/include/string.h b/nolibc/include/string.h index 226325e5..da7bc6d5 100644 --- a/nolibc/include/string.h +++ b/nolibc/include/string.h @@ -10,6 +10,7 @@ void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); int strcmp(const char *, const char *); size_t strlen(const char *); +size_t strnlen(const char *, size_t); char *strerror(int); /* * The following definitions are not required by the OCaml runtime, but are diff --git a/nolibc/strnlen.c b/nolibc/strnlen.c new file mode 100644 index 00000000..9f90a18a --- /dev/null +++ b/nolibc/strnlen.c @@ -0,0 +1,20 @@ +#include +#include +#include + +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) + +size_t strnlen(const char *s, size_t maxlen) +{ + const char *a = s; + const size_t *w; + size_t over = maxlen; + for (; ((uintptr_t)s % ALIGN) && over; s++, over--) if (!*s) return s-a; + for (w = (const void *)s; over>ALIGN && !HASZERO(*w); w++,over-=ALIGN); + for (s = (const void *)w; *s && over; s++, over--); + if (over) return s-a; + else return maxlen; +} From 03d851797a8d6578f82bae3de363f98a7761b237 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 27 Feb 2024 16:12:18 +0100 Subject: [PATCH 54/92] Define some extra `errno` values --- nolibc/include/errno.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index 54a52abc..fd3a6660 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -2,14 +2,17 @@ #define _ERRNO_H extern int errno; -#define EBADF 9 /* Bad file number */ -#define ENOENT 2 /* No such file or directory */ -#define ENOMEM 12 /* Out of memory */ -#define EBUSY 16 /* Device or resource busy */ -#define EINVAL 22 /* Invalid argument */ -#define EMFILE 24 /* Too many open files */ -#define ERANGE 34 /* Math result not representable */ -#define ENOSYS 38 /* Invalid system call number */ -#define EOVERFLOW 75 /* Value too large for defined data type */ +#define EBADF 9 /* Bad file number */ +#define ENOENT 2 /* No such file or directory */ +#define ENOMEM 12 /* Out of memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EINVAL 22 /* Invalid argument */ +#define EMFILE 24 /* Too many open files */ +#define ERANGE 34 /* Math result not representable */ +#define ENOSYS 38 /* Invalid system call number */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define EINTR 4 /* Interrupted system call */ +#define EPIPE 32 /* Broken pipe */ +#define ECONNRESET 104 /* Connection reset by peer */ #endif From 9469b19c390c5334578bfcf8ea930918d4c3ae30 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 27 Feb 2024 14:09:00 +0100 Subject: [PATCH 55/92] Use the compiler-provided `stdatomic.h` Use the builtin implementation of atomics of the compiler instead of a dummy one The compiler-provided `stdatomic.h` follows our constraints. Even if it is not explicitly listed in the freestanding headers: - clang still enables it with `-nostdlibinc` that the solo5 toolchain uses, - all gcc headers are brought into view anyway, - those headers respect `-ffreestanding` (ie they do not pull unwanted headers when `-ffreestanding` is enabled). --- nolibc/include/stdatomic.h | 69 -------------------------------------- nolibc/stubs.c | 7 ---- 2 files changed, 76 deletions(-) delete mode 100644 nolibc/include/stdatomic.h diff --git a/nolibc/include/stdatomic.h b/nolibc/include/stdatomic.h deleted file mode 100644 index 6ab87ddd..00000000 --- a/nolibc/include/stdatomic.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _STDATOMIC_H -#define _STDATOMIC_H - -// Compatibility with non-clang compilers -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -#define atomic_load_explicit(x, mode) ( *x ) -#define atomic_load(x) ( *x ) - -extern int memory_order_release; -extern int memory_order_acquire; -extern int memory_order_relaxed; -extern int memory_order_seq_cst; - -#if __has_builtin(__c11_atomic_fetch_add) -#define atomic_fetch_add(X, Y) __c11_atomic_fetch_add(X, Y, __ATOMIC_SEQ_CST) -#else -#define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; }) -#endif - -#define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y) - -#define atomic_thread_fence(MO) do {} while (0) - -typedef unsigned long long atomic_uint_fast64_t; - -#if __has_builtin(__c11_atomic_compare_exchange_strong) -#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ - __c11_atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED, \ - __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) -#else -#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \ - ({ int ret = 0; \ - if (*OBJ == *EXPECTED) { \ - *OBJ = DESIRED; \ - ret = 1; \ - } \ - ret; \ - }) -#endif - -#if __has_builtin(__c11_atomic_exchange) -#define atomic_exchange(OBJ, DESIRED) \ - __c11_atomic_exchange(OBJ, DESIRED, __ATOMIC_SEQ_CST) -#else -#define atomic_exchange(OBJ, DESIRED) \ - ({ __auto_type tmp = *OBJ; \ - *OBJ = DESIRED; \ - tmp; \ - }) -#endif - -#define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0) -#define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED) - -#if __has_builtin(__c11_atomic_fetch_or) -#define atomic_fetch_or(OBJ, ARG) \ - __c11_atomic_fetch_or(OBJ, ARG, __ATOMIC_SEQ_CST) -#else -#define atomic_fetch_or(OBJ, ARG) \ - ({ __auto_type tmp = *OBJ; \ - *OBJ = *OBJ | ARG; \ - tmp; \ - }) -#endif - -#endif diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 65a458c4..c8c0b2ec 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -113,13 +113,6 @@ STUB_IGNORE(int, pthread_attr_init, 0); STUB_ABORT(pthread_cleanup_push); STUB_ABORT(pthread_cleanup_pop); -int memory_order_release; -int memory_order_acquire; -int memory_order_relaxed; - -STUB_ABORT(atomic_store_explicit); -STUB_ABORT(atomic_exchange); - /* above that line, for OCaml 5, those are only required (i guess) for the configure step */ STUB_IGNORE(int, pthread_mutex_lock, 0); STUB_IGNORE(int, pthread_mutex_trylock, 0); From 295bf175c9c42d07ca265e79dbe4fe1eb0f6417d Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 28 Mar 2024 15:02:58 +0100 Subject: [PATCH 56/92] Do not rebuild `nolibc.a` when nothing changed Remove the dependency from `nolibc.a` to a phony target that forces running `ar` on all builds The dependency to the test target is moved to `all` --- nolibc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nolibc/Makefile b/nolibc/Makefile index 12eb5bcc..8e3515a8 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -5,7 +5,7 @@ ifeq ($(SYSDEP_OBJS),) $(error SYSDEP_OBJS not set) endif -all: libnolibc.a +all: libnolibc.a test-headers .PHONY: all test-headers clean @@ -29,7 +29,7 @@ OBJS=assert.o \ dtoa.o: CFLAGS+=-fno-strict-aliasing -libnolibc.a: $(OBJS) $(SYSDEP_OBJS) test-headers +libnolibc.a: $(OBJS) $(SYSDEP_OBJS) $(AR) rcs $@ $(OBJS) $(SYSDEP_OBJS) # The following test ensures that each header file provided by nolibc is both From 7bce94ad9f55757616ef96bc33d810a10d3fe97d Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 26 Mar 2024 19:07:35 +0100 Subject: [PATCH 57/92] Trim down `configure.sh` and adapt Makefiles - SYSDEP_OBJS is constant so move it to the relevant Makefile - MAKECONF_CFLAGS is always empty so remove it - Drop the variables concerning the build machine - Rename the variables concerning the target using TARGET (rather than BUILD) - Remove aspects that are to be moved to a new solo5-ocaml toolchain: - adding explicitly the libgcc for the aarch64 target - picking the exact version and options of commands --- Makefile | 12 ++++++------ configure.sh | 51 ++++++------------------------------------------- nolibc/Makefile | 5 ++--- 3 files changed, 14 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index dac400f8..bbcdb1db 100644 --- a/Makefile +++ b/Makefile @@ -16,14 +16,15 @@ GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -Wl,--start-group -ln # NOLIBC NOLIBC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include nolibc/libnolibc.a: - $(MAKE) -C nolibc \ - "CC=$(MAKECONF_CC)" \ - "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" \ - "SYSDEP_OBJS=$(MAKECONF_NOLIBC_SYSDEP_OBJS)" + $(MAKE) -C nolibc libnolibc.a \ + "CC=$(MAKECONF_TOOLCHAIN)-cc" \ + "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" # OPENLIBM openlibm/libopenlibm.a: - $(MAKE) -C openlibm "CC=$(MAKECONF_CC)" "CPPFLAGS=$(LOCAL_CFLAGS)" libopenlibm.a + $(MAKE) -C openlibm libopenlibm.a \ + "CC=$(MAKECONF_TOOLCHAIN)-cc" \ + "CPPFLAGS=$(LOCAL_CFLAGS)" # OCAML ocaml/Makefile: @@ -144,7 +145,6 @@ clean: $(MAKE) -C openlibm clean $(MAKE) -C nolibc \ "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" \ - "SYSDEP_OBJS=$(MAKECONF_NOLIBC_SYSDEP_OBJS)" \ clean distclean: clean diff --git a/configure.sh b/configure.sh index db34fac0..61fde5e6 100755 --- a/configure.sh +++ b/configure.sh @@ -31,7 +31,6 @@ EOM OCAML_CONFIGURE_OPTIONS= MAKECONF_PREFIX=/usr/local -CC=cc while [ $# -gt 0 ]; do OPT="$1" @@ -60,61 +59,23 @@ done [ -z "${CONFIG_TARGET}" ] && die "The --target option needs to be specified." -MAKECONF_CFLAGS="" -MAKECONF_CC="$CONFIG_TARGET-cc" -MAKECONF_LD="$CONFIG_TARGET-ld" -MAKECONF_AS="$MAKECONF_CC -c" +TARGET_TRIPLET="$("$CONFIG_TARGET-cc" -dumpmachine)" -BUILD_TRIPLET="$($MAKECONF_CC -dumpmachine)" -OCAML_BUILD_ARCH= - -# Canonicalize BUILD_ARCH and set OCAML_BUILD_ARCH. The former is for autoconf, -# the latter for the rest of the OCaml build system. -case "${BUILD_TRIPLET}" in +case "${TARGET_TRIPLET}" in amd64-*|x86_64-*) - BUILD_ARCH="x86_64" - OCAML_BUILD_ARCH="amd64" + TARGET_ARCH="x86_64" ;; aarch64-*) - BUILD_ARCH="aarch64" - OCAML_BUILD_ARCH="arm64" + TARGET_ARCH="aarch64" ;; *) - die "Unsupported build architecture: ${BUILD_TRIPLET}" + die "Unsupported build architecture: ${TARGET_TRIPLET}" ;; esac -TRIPLET="$($CC -dumpmachine)" -ARCH= - -case "${TRIPLET}" in - amd64-*|x86_64-*) - ARCH="x86_64" - ;; - aarch64-*) - ARCH="aarch64" - ;; - *) - die "Unsupported host architecture: ${TRIPLET}" - ;; -esac - -EXTRA_LIBS= -if [ "${BUILD_ARCH}" = "aarch64" ]; then - EXTRA_LIBS="$EXTRA_LIBS -lgcc" || exit 1 -fi - cat <Makeconf MAKECONF_PREFIX=${MAKECONF_PREFIX} -MAKECONF_CFLAGS=${MAKECONF_CFLAGS} MAKECONF_TOOLCHAIN=${CONFIG_TARGET} -MAKECONF_CC=${MAKECONF_CC} -MAKECONF_LD=${MAKECONF_LD} -MAKECONF_AS=${MAKECONF_AS} -MAKECONF_ARCH=${ARCH} -MAKECONF_BUILD_ARCH=${BUILD_ARCH} -MAKECONF_OCAML_BUILD_ARCH=${OCAML_BUILD_ARCH} +MAKECONF_TARGET_ARCH=${TARGET_ARCH} MAKECONF_OCAML_CONFIGURE_OPTIONS=${OCAML_CONFIGURE_OPTIONS} -MAKECONF_NOLIBC_SYSDEP_OBJS=sysdeps_solo5.o -MAKECONF_EXTRA_LIBS=${EXTRA_LIBS} EOM diff --git a/nolibc/Makefile b/nolibc/Makefile index 8e3515a8..99a3a860 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -1,9 +1,6 @@ ifeq ($(FREESTANDING_CFLAGS),) $(error FREESTANDING_CFLAGS not set) endif -ifeq ($(SYSDEP_OBJS),) - $(error SYSDEP_OBJS not set) -endif all: libnolibc.a test-headers @@ -29,6 +26,8 @@ OBJS=assert.o \ dtoa.o: CFLAGS+=-fno-strict-aliasing +SYSDEP_OBJS=sysdeps_solo5.o + libnolibc.a: $(OBJS) $(SYSDEP_OBJS) $(AR) rcs $@ $(OBJS) $(SYSDEP_OBJS) From 5b97aa722c5a07c8b88010af17508d032432c91d Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 11:25:23 +0200 Subject: [PATCH 58/92] Clean up typos in `configure.sh` Use `${OPT#*=}` to remove only up to the first `=` (in case more than one appear in the argument) --- configure.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.sh b/configure.sh index 61fde5e6..c1a415c2 100755 --- a/configure.sh +++ b/configure.sh @@ -19,7 +19,7 @@ usage() usage: ${prog_NAME} [ OPTIONS ] Configures the ocaml-solo5 build system. Options: - --prefix=DIR: + --prefix=DIR Installation prefix (default: /usr/local). --target=TARGET Solo5 compiler toolchain to use. @@ -37,13 +37,13 @@ while [ $# -gt 0 ]; do case "${OPT}" in --target=*) - CONFIG_TARGET="${OPT##*=}" + CONFIG_TARGET="${OPT#*=}" ;; --prefix=*) - MAKECONF_PREFIX="${OPT##*=}" + MAKECONF_PREFIX="${OPT#*=}" ;; --ocaml-configure-option=*) - OCAML_CONFIGURE_OPTIONS="${OCAML_CONFIGURE_OPTIONS} ${OPT##*=}" + OCAML_CONFIGURE_OPTIONS="${OCAML_CONFIGURE_OPTIONS} ${OPT#*=}" ;; --help) usage From f63f9cd4dd2116942b1de70893e0a937193ca87b Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 5 Apr 2024 15:07:47 +0200 Subject: [PATCH 59/92] Add a `sysroot` configuration option --- configure.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.sh b/configure.sh index c1a415c2..679e5a33 100755 --- a/configure.sh +++ b/configure.sh @@ -21,6 +21,9 @@ Configures the ocaml-solo5 build system. Options: --prefix=DIR Installation prefix (default: /usr/local). + --sysroot=DIR + Installation prefix for the OCaml cross-compiler and its supporting + libraries (default: /lib/ocaml-solo5). --target=TARGET Solo5 compiler toolchain to use. --ocaml-configure-option=OPTION @@ -42,6 +45,9 @@ while [ $# -gt 0 ]; do --prefix=*) MAKECONF_PREFIX="${OPT#*=}" ;; + --sysroot=*) + MAKECONF_SYSROOT="${OPT#*=}" + ;; --ocaml-configure-option=*) OCAML_CONFIGURE_OPTIONS="${OCAML_CONFIGURE_OPTIONS} ${OPT#*=}" ;; @@ -57,6 +63,8 @@ while [ $# -gt 0 ]; do shift done +MAKECONF_SYSROOT="${MAKECONF_SYSROOT:-$MAKECONF_PREFIX/lib/ocaml-solo5}" + [ -z "${CONFIG_TARGET}" ] && die "The --target option needs to be specified." TARGET_TRIPLET="$("$CONFIG_TARGET-cc" -dumpmachine)" @@ -75,6 +83,7 @@ esac cat <Makeconf MAKECONF_PREFIX=${MAKECONF_PREFIX} +MAKECONF_SYSROOT=${MAKECONF_SYSROOT} MAKECONF_TOOLCHAIN=${CONFIG_TARGET} MAKECONF_TARGET_ARCH=${TARGET_ARCH} MAKECONF_OCAML_CONFIGURE_OPTIONS=${OCAML_CONFIGURE_OPTIONS} From 5b830b38e7d888ea05283eb1f6131c8586943f25 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 11:47:20 +0200 Subject: [PATCH 60/92] Create a OCaml/Solo5-specific cross toolchain Add a script to generate all the tools of a OCaml/Solo5 specific toolchain, using the `ARCH-solo5-ocaml-` tool prefix, in order to: - allow to have a clean way to point to the build directories in `-I` and `-L` options for nolibc and openlibm during the build, and to the installed directories after installation - build upon the toolchain autoconfiguration in OCaml's configure, so that it is not necessary to override each tool separately Add Makefile recipes to build the two variants of the toolchain, the one for build and the one to be installed Add a configure option to set up the tool prefix to use for the binutils that are not part of the Solo5 toolchain --- Makefile | 50 +++++++++++++++++ configure.sh | 9 +++ gen_toolchain_tool.sh | 124 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100755 gen_toolchain_tool.sh diff --git a/Makefile b/Makefile index bbcdb1db..c2ac8e05 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,56 @@ openlibm/libopenlibm.a: "CC=$(MAKECONF_TOOLCHAIN)-cc" \ "CPPFLAGS=$(LOCAL_CFLAGS)" +# TOOLCHAIN +# We create prefix-gcc even when the actual compiler will be Clang because +# autoconf toolchain detection will pick the first compiler that exists in the +# list: prefix-gcc, gcc, prefix-cc, cc... +# Anyway, configure scripts always explicitly test whether the compiler defines +# Clang-specific macros when they want to distinguish GCC and Clang +ALLTOOLS := gcc cc ar as ld nm objcopy objdump ranlib readelf strip +ALLTOOLS := $(foreach tool,$(ALLTOOLS), \ + $(MAKECONF_TARGET_ARCH)-solo5-ocaml-$(tool)) + +TOOLDIR_FOR_BUILD := _build/build-toolchain +TOOLCHAIN_FOR_BUILD := $(addprefix $(TOOLDIR_FOR_BUILD)/,$(ALLTOOLS)) +TOOLDIR_FINAL := _build/toolchain +TOOLCHAIN_FINAL := $(addprefix $(TOOLDIR_FINAL)/,$(ALLTOOLS)) + +# Options for the build version of the tools +TOOLCHAIN_BUILD_CFLAGS := -I$(TOP)/nolibc/include \ + -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src +TOOLCHAIN_BUILD_LDFLAGS := -L$(TOP)/nolibc -L$(TOP)/openlibm + +# Options for the installed version of the tools +TOOLCHAIN_FINAL_CFLAGS := -I$(MAKECONF_SYSROOT)/include +TOOLCHAIN_FINAL_LDFLAGS := -L$(MAKECONF_SYSROOT)/lib + +$(TOOLDIR_FOR_BUILD) $(TOOLDIR_FINAL): + mkdir -p $@ + +$(TOOLDIR_FOR_BUILD)/$(MAKECONF_TARGET_ARCH)-solo5-ocaml-%: \ + gen_toolchain_tool.sh | $(TOOLDIR_FOR_BUILD) + ARCH="$(MAKECONF_TARGET_ARCH)" \ + SOLO5_TOOLCHAIN="$(MAKECONF_TOOLCHAIN)" \ + OTHERTOOLPREFIX="$(MAKECONF_TOOLPREFIX)" \ + TOOL_CFLAGS="$(TOOLCHAIN_BUILD_CFLAGS)" \ + TOOL_LDFLAGS="$(TOOLCHAIN_BUILD_LDFLAGS)" \ + sh $< $* > $@ + chmod +x $@ + +$(TOOLDIR_FINAL)/$(MAKECONF_TARGET_ARCH)-solo5-ocaml-%: \ + gen_toolchain_tool.sh | $(TOOLDIR_FINAL) + ARCH="$(MAKECONF_TARGET_ARCH)" \ + SOLO5_TOOLCHAIN="$(MAKECONF_TOOLCHAIN)" \ + OTHERTOOLPREFIX="$(MAKECONF_TOOLPREFIX)" \ + TOOL_CFLAGS="$(TOOLCHAIN_FINAL_CFLAGS)" \ + TOOL_LDFLAGS="$(TOOLCHAIN_FINAL_LDFLAGS)" \ + sh $< $* > $@ + chmod +x $@ + +.PHONY: toolchains +toolchains: $(TOOLCHAIN_FOR_BUILD) $(TOOLCHAIN_FINAL) + # OCAML ocaml/Makefile: cp -r `ocamlfind query ocaml-src` ./ocaml diff --git a/configure.sh b/configure.sh index 679e5a33..f9dfd870 100755 --- a/configure.sh +++ b/configure.sh @@ -26,6 +26,9 @@ Options: libraries (default: /lib/ocaml-solo5). --target=TARGET Solo5 compiler toolchain to use. + --othertoolprefix=PREFIX + Prefix for tools besides the Solo5 toolchain + (default: \`TARGET-cc -dumpmachine\`-). --ocaml-configure-option=OPTION Add an option to the OCaml compiler configuration. EOM @@ -42,6 +45,9 @@ while [ $# -gt 0 ]; do --target=*) CONFIG_TARGET="${OPT#*=}" ;; + --othertoolprefix=*) + MAKECONF_TOOLPREFIX="${OPT#*=}" + ;; --prefix=*) MAKECONF_PREFIX="${OPT#*=}" ;; @@ -69,6 +75,8 @@ MAKECONF_SYSROOT="${MAKECONF_SYSROOT:-$MAKECONF_PREFIX/lib/ocaml-solo5}" TARGET_TRIPLET="$("$CONFIG_TARGET-cc" -dumpmachine)" +MAKECONF_TOOLPREFIX="${MAKECONF_TOOLPREFIX:-$TARGET_TRIPLET-}" + case "${TARGET_TRIPLET}" in amd64-*|x86_64-*) TARGET_ARCH="x86_64" @@ -85,6 +93,7 @@ cat <Makeconf MAKECONF_PREFIX=${MAKECONF_PREFIX} MAKECONF_SYSROOT=${MAKECONF_SYSROOT} MAKECONF_TOOLCHAIN=${CONFIG_TARGET} +MAKECONF_TOOLPREFIX=${MAKECONF_TOOLPREFIX} MAKECONF_TARGET_ARCH=${TARGET_ARCH} MAKECONF_OCAML_CONFIGURE_OPTIONS=${OCAML_CONFIGURE_OPTIONS} EOM diff --git a/gen_toolchain_tool.sh b/gen_toolchain_tool.sh new file mode 100755 index 00000000..32177c80 --- /dev/null +++ b/gen_toolchain_tool.sh @@ -0,0 +1,124 @@ +#!/bin/sh + +# Generate a wrapper for Solo5 (G)CC, ld, objcopy and any other binutil +# Expected argument: the tool to generate +# Expected environment variables: +# ARCH: the target architecture (x86_64 or aarch64) +# TOOL_CFLAGS and TOOL_LDFLAGS: extra flags +# SOLO5_TOOLCHAIN: the target for the wrapped Solo5 toolchain +# OTHERTOOLPREFIX: the prefix for tools not in the Solo5 toolchain +# TARGET_X: overrides the command for binutil X + +gen_cc() { + # Note that -nostdlib is not required, as it is injected by Solo5' cc, ld + + CFLAGS="$TOOL_CFLAGS" + LDFLAGS="$TOOL_LDFLAGS" + EXTRALIBS="" + + case "$ARCH" in + aarch64) + EXTRALIBS="-lgcc" + ;; + esac + + cat << EOF +#!/bin/sh + +# Just like the Solo5 cc, we assume that we are linking, unless we find an +# argument suggesting we are compiling but we call Solo5' cc regardless + +compiling= +for arg in "\$@"; do + case "\$arg" in + -[cSE]) + compiling="\$arg" + break + ;; + esac +done + +set -- \\ + $CFLAGS \\ + -include _solo5/overrides.h \\ + "\$@" + +if [ -z "\$compiling" ]; then + # linking options + set -- \\ + "\$@" \\ + $LDFLAGS \\ + -Wl,--start-group \\ + -lnolibc \\ + -lopenlibm \\ + $EXTRALIBS \\ + -Wl,--end-group +fi + +[ -n "\${__V}" ] && set -x +exec "$SOLO5_TOOLCHAIN-cc" "\$@" +EOF +} + +gen_tool() { + TOOL="$1" + case "$TOOL" in + ar) + TARGET_TOOL="$TARGET_AR" + ;; + as) + TARGET_TOOL="$TARGET_AS" + ;; + ld) + TARGET_TOOL="$TARGET_LD" + ;; + nm) + TARGET_TOOL="$TARGET_NM" + ;; + objcopy) + TARGET_TOOL="$TARGET_OBJCOPY" + ;; + objdump) + TARGET_TOOL="$TARGET_OBJDUMP" + ;; + ranlib) + TARGET_TOOL="$TARGET_RANLIB" + ;; + readelf) + TARGET_TOOL="$TARGET_READELF" + ;; + strip) + TARGET_TOOL="$TARGET_STRIP" + ;; + esac + if test "$TARGET_TOOL" ; then + TOOL="$TARGET_TOOL" + elif command -v -- "$SOLO5_TOOLCHAIN-$TOOL" > /dev/null; then + TOOL="$SOLO5_TOOLCHAIN-$TOOL" + else + case "$TOOL" in + as) + TOOL="$SOLO5_TOOLCHAIN-cc -c" + ;; + *) + if command -v -- "$OTHERTOOLPREFIX$TOOL" > /dev/null; then + TOOL="$OTHERTOOLPREFIX$TOOL" + fi + ;; + esac + fi + + cat << EOF +#!/bin/sh +exec $TOOL "\$@" +EOF +} + +case "$1" in + cc|gcc) + gen_cc + ;; + *) + gen_tool "$1" + ;; +esac From 0990c75d4f947cf06af9eebbbfac399b6a573e3b Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 12:30:44 +0200 Subject: [PATCH 61/92] Define __BSD_VISIBLE and __XSI_VISIBLE when compiling C files Define openlibm's __BSD_VISIBLE and __XSI_VISIBLE to false when compiling C files openlibm headers use those macros to detect BSD and X/Open, but solo5 is neither When left undefined, compiling openlibm generates warnings when compiling OCaml (those warnings are turned into errors when compiling development versions of the compiler) --- gen_toolchain_tool.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gen_toolchain_tool.sh b/gen_toolchain_tool.sh index 32177c80..2a5a554d 100755 --- a/gen_toolchain_tool.sh +++ b/gen_toolchain_tool.sh @@ -41,6 +41,8 @@ done set -- \\ $CFLAGS \\ -include _solo5/overrides.h \\ + -D__BSD_VISIBLE=0 \\ + -D__XSI_VISIBLE=0 \\ "\$@" if [ -z "\$compiling" ]; then From 3180b5ddb26b81b67805b93933c1096128332987 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 16 Apr 2024 19:42:34 +0200 Subject: [PATCH 62/92] Disable a Clang warning Disable Clang's unused-command-line-argument warning that triggers often as our toolchain is not smart enough to generate only useful arguments for each call --- gen_toolchain_tool.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gen_toolchain_tool.sh b/gen_toolchain_tool.sh index 2a5a554d..e711ad30 100755 --- a/gen_toolchain_tool.sh +++ b/gen_toolchain_tool.sh @@ -22,6 +22,13 @@ gen_cc() { ;; esac + # Add the -Wno-unused-command-line-argument option for clang, as we always + # give it compiling options, even if it will be only linking + # Reuse the test from Solo5 to detect clang + if "$SOLO5_TOOLCHAIN-cc" -dM -E - Date: Thu, 4 Apr 2024 13:19:28 +0200 Subject: [PATCH 63/92] Clean up options to build libraries Following the introduction of the OCaml/Solo5 toolchain, clean up all the options used to build the libraries --- Makefile | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index c2ac8e05..20171c36 100644 --- a/Makefile +++ b/Makefile @@ -6,15 +6,11 @@ all: openlibm/libopenlibm.a nolibc/libnolibc.a ocaml solo5.conf TOP=$(abspath .) -# CFLAGS used to build nolibc / openlibm / ocaml runtime -LOCAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(TOP)/nolibc/include -include _solo5/overrides.h -# CFLAGS used by the OCaml compiler to build C stubs -GLOBAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(MAKECONF_PREFIX)/solo5-sysroot/include/nolibc/ -include _solo5/overrides.h -# LIBS used by the OCaml compiler to link executables -GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -Wl,--start-group -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS) -Wl,--end-group +# CFLAGS used to build the nolibc and openlibm libraries +LIB_CFLAGS=-I$(TOP)/nolibc/include -include _solo5/overrides.h # NOLIBC -NOLIBC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include +NOLIBC_CFLAGS=$(LIB_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include nolibc/libnolibc.a: $(MAKE) -C nolibc libnolibc.a \ "CC=$(MAKECONF_TOOLCHAIN)-cc" \ @@ -24,7 +20,7 @@ nolibc/libnolibc.a: openlibm/libopenlibm.a: $(MAKE) -C openlibm libopenlibm.a \ "CC=$(MAKECONF_TOOLCHAIN)-cc" \ - "CPPFLAGS=$(LOCAL_CFLAGS)" + "CPPFLAGS=$(LIB_CFLAGS)" # TOOLCHAIN # We create prefix-gcc even when the actual compiler will be Clang because From 060a037fbc5c4250b14690e8466760ef6e24dcf9 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 13:02:02 +0200 Subject: [PATCH 64/92] Use OCaml's cross-compiler-aware configure and make Use OCaml's cross-compiler-aware versions of configure and make, which are able to detect the toolchain using only the configure `--target` argument Until this is available upstream, this is to be provided through local patches Reorganise Makefile targets so that `ocaml` is no longer both a directory and a phony target to build the compiler: - the `ocaml` target now creates the `ocaml` directory from the content of the `ocaml-src` package and then applies patches found in `patches//` - an empty `_build/ocaml_is_built` file is used to record whether, and when, the compiler was built Note that it is still possible to build a OCaml/Solo5 for a version of the compiler for which no `ocaml-src` is available by creating directly the `ocaml` directory --- .gitignore | 1 + Makefile | 136 ++++++++++++++++------------------------------------- 2 files changed, 41 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index 5c6b00dc..8627418a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ nolibc/*.a nolibc/test-include/ ocaml/ _build/ +/ocaml-src.tar.gz diff --git a/Makefile b/Makefile index 20171c36..1c7ed241 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,14 @@ all: openlibm/libopenlibm.a nolibc/libnolibc.a ocaml solo5.conf TOP=$(abspath .) +# Most parts (OCaml, nolibc, openlibm) currently build their result in-tree but +# we reuse dune's `_build` dir, as familiar and already usable for `example`, +# etc., for some generated files +_build: + mkdir -p $@ + +LIBS := openlibm/libopenlibm.a nolibc/libnolibc.a + # CFLAGS used to build the nolibc and openlibm libraries LIB_CFLAGS=-I$(TOP)/nolibc/include -include _solo5/overrides.h @@ -73,108 +81,44 @@ $(TOOLDIR_FINAL)/$(MAKECONF_TARGET_ARCH)-solo5-ocaml-%: \ toolchains: $(TOOLCHAIN_FOR_BUILD) $(TOOLCHAIN_FINAL) # OCAML -ocaml/Makefile: - cp -r `ocamlfind query ocaml-src` ./ocaml - -# OCaml >= 4.08.0 uses an autotools-based build system. In this case we -# convince it to think it's using the Solo5 compiler as a cross compiler, and -# let the build system do its work with as little additional changes on our -# side as possible. -# -# Notes: -# -# - CPPFLAGS must be set for configure as well as CC, otherwise it complains -# about headers due to differences of opinion between the preprocessor and -# compiler. -# - ARCH must be overridden manually in Makefile.config due to the use of -# hardcoded combinations in the OCaml configure. -# - We use LIBS with a stubbed out solo5 implementation to override the OCaml -# configure link test -# - We override OCAML_OS_TYPE since configure just hardcodes it to "Unix". -OC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src -nostdlib -OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -Wl,--start-group -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) -Wl,--end-group -ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a -# configure: Do not build dynlink - sed -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure > ocaml/configure.sed && \ - mv ocaml/configure.sed ocaml/configure -# configure: Allow precise input of flags and libs - sed -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \ - mv ocaml/configure.sed ocaml/configure - sed -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \ - mv ocaml/configure.sed ocaml/configure - sed -e 's/nativecclibs="$$cclibs $$DLLIBS $$PTHREAD_LIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \ - mv ocaml/configure.sed ocaml/configure - sed -e 's/^arch=none$$/arch=$(MAKECONF_OCAML_BUILD_ARCH)/' ocaml/configure > ocaml/configure.sed && \ - mv ocaml/configure.sed ocaml/configure - chmod +x ocaml/configure -# Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system - sed -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/Makefile > ocaml/Makefile.sed && \ - mv ocaml/Makefile.sed ocaml/Makefile - sed -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/Makefile > ocaml/Makefile.sed && \ - mv ocaml/Makefile.sed ocaml/Makefile - sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/Makefile > ocaml/Makefile.sed && \ - mv ocaml/Makefile.sed ocaml/Makefile - sed -e 's,^coldstart: $(COLDSTART_DEPS)$$,coldstart: runtime/primitives $$(COLDSTART_DEPS),' ocaml/Makefile > ocaml/Makefile.sed && \ - mv ocaml/Makefile.sed ocaml/Makefile - echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/Makefile - echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/Makefile - echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/Makefile - echo -e "runtime/ocamlrun\$$(EXE):\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile - echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile - echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile -# yacc/Makefile: import ocamlyacc from the system - sed -e 's,^$$(ocamlyacc_PROGRAM)$$(EXE):.*,dummy_yacc:,g' ocaml/Makefile > ocaml/Makefile.sed && \ - mv ocaml/Makefile.sed ocaml/Makefile - echo -e "\$$(ocamlyacc_PROGRAM)\$$(EXE):\n\tcp $(shell which ocamlyacc) yacc/\n" >> ocaml/Makefile -# patch ocaml 5.0.0 runtime for single domain/thread solo5 - sed -e 's/#define Max_domains 128/#define Max_domains 1/' ocaml/runtime/caml/domain.h > ocaml/runtime/caml/domain.h.sed && \ - mv ocaml/runtime/caml/domain.h.sed ocaml/runtime/caml/domain.h +# Extract sources from the ocaml-src package and apply patches if there any in +# `patches//` +ocaml: +# First make sure the ocaml directory doesn't exist, otherwise the cp would +# create an ocaml-src subdirectory + test ! -d $@ + cp -r "$$(ocamlfind query ocaml-src)" $@ + VERSION="$$(head -n1 ocaml/VERSION)" ; \ + if test -d "patches/$$VERSION" ; then \ + git apply --directory=$@ "patches/$$VERSION"/*; \ + fi + # av_cv_libm_cos=no is passed to configure to prevent -lm being used (which # would use the host system libm instead of the freestanding openlibm, see # https://github.com/mirage/ocaml-solo5/issues/101 +ocaml/Makefile.config: $(LIBS) $(TOOLCHAIN_FOR_BUILD) | ocaml + PATH="$$PWD/$(TOOLDIR_FOR_BUILD):$$PATH" ; \ cd ocaml && \ - CC="$(MAKECONF_CC)" \ - OC_CFLAGS="$(OC_CFLAGS)" \ - OCAMLC_CFLAGS="$(GLOBAL_CFLAGS)" \ - AS="$(MAKECONF_AS)" \ - ASPP="$(MAKECONF_CC) $(OC_CFLAGS) -c" \ - CPPFLAGS="$(OC_CFLAGS)" \ - LIBS="$(OC_LIBS)"\ - GLOBAL_LIBS="$(GLOBAL_LIBS)"\ - LD="$(MAKECONF_LD)" \ - ac_cv_prog_DIRECT_LD="$(MAKECONF_LD)" \ - ac_cv_lib_m_cos="no" \ + ac_cv_lib_m_cos="no" \ ./configure \ - -host=$(MAKECONF_ARCH)-unknown-none \ - -target=$(MAKECONF_BUILD_ARCH)-solo5-none \ - -prefix $(MAKECONF_PREFIX)/solo5-sysroot \ - -disable-shared\ - -disable-systhreads\ - -disable-unix-lib\ - -disable-instrumented-runtime\ - -disable-debug-runtime\ - -disable-ocamltest\ - -disable-ocamldoc\ + --target="$(MAKECONF_TARGET_ARCH)-solo5-ocaml" \ + --prefix="$(MAKECONF_SYSROOT)" \ + --disable-shared \ + --disable-systhreads \ + --disable-unix-lib \ + --disable-instrumented-runtime \ + --disable-debug-runtime \ + --disable-ocamltest \ + --disable-ocamldoc \ + --without-zstd \ $(MAKECONF_OCAML_CONFIGURE_OPTIONS) - echo 'NATIVE_COMPILER=true' >> ocaml/Makefile.config - echo 'SAK_CC=cc' >> ocaml/Makefile.config - echo 'SAK_CFLAGS=' >> ocaml/Makefile.config - echo 'SAK_LINK=cc $(SAK_CFLAGS) $$(OUTPUTEXE)$$(1) $$(2)' >> ocaml/Makefile.config - echo '#undef OCAML_OS_TYPE' >> ocaml/runtime/caml/s.h - echo '#define OCAML_OS_TYPE "None"' >> ocaml/runtime/caml/s.h - -# NOTE: ocaml/tools/make-version-header.sh is integrated into OCaml's ./configure script starting from OCaml 4.14 -ifneq (,$(wildcard ocaml/tools/make-version-header.sh)) -ocaml/runtime/caml/version.h: ocaml/Makefile.config - ocaml/tools/make-version-header.sh > $@ -else -ocaml/runtime/caml/version.h: ocaml/Makefile.config - @ -endif - -ocaml: ocaml/Makefile.config ocaml/runtime/caml/version.h - $(MAKE) -C ocaml world - $(MAKE) -C ocaml opt + +OCAML_IS_BUILT := _build/ocaml_is_built +$(OCAML_IS_BUILT): ocaml/Makefile.config | _build + PATH="$$PWD/$(TOOLDIR_FOR_BUILD):$$PATH" $(MAKE) -C ocaml cross.opt + cd ocaml && ocamlrun tools/stripdebug ocamlc ocamlc.tmp + cd ocaml && ocamlrun tools/stripdebug ocamlopt ocamlopt.tmp + touch $@ # CONFIGURATION FILES solo5.conf: solo5.conf.in From 02af86228cc03f371f0582927d8ef8329a0af553 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 13:59:46 +0200 Subject: [PATCH 65/92] Remove workaround for #101 The specific toolchain allow the proper detection of the math library --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index 1c7ed241..b2c56db8 100644 --- a/Makefile +++ b/Makefile @@ -93,13 +93,9 @@ ocaml: git apply --directory=$@ "patches/$$VERSION"/*; \ fi -# av_cv_libm_cos=no is passed to configure to prevent -lm being used (which -# would use the host system libm instead of the freestanding openlibm, see -# https://github.com/mirage/ocaml-solo5/issues/101 ocaml/Makefile.config: $(LIBS) $(TOOLCHAIN_FOR_BUILD) | ocaml PATH="$$PWD/$(TOOLDIR_FOR_BUILD):$$PATH" ; \ cd ocaml && \ - ac_cv_lib_m_cos="no" \ ./configure \ --target="$(MAKECONF_TARGET_ARCH)-solo5-ocaml" \ --prefix="$(MAKECONF_SYSROOT)" \ From a68c8562ff697b3680130d8177af331e8bec7896 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 28 Mar 2024 18:11:31 +0100 Subject: [PATCH 66/92] Generate `solo5.conf` with available .opt programs --- Makefile | 5 ++--- gen_solo5_conf.sh | 20 ++++++++++++++++++++ solo5.conf.in | 8 -------- 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100755 gen_solo5_conf.sh delete mode 100644 solo5.conf.in diff --git a/Makefile b/Makefile index b2c56db8..776eab72 100644 --- a/Makefile +++ b/Makefile @@ -117,9 +117,8 @@ $(OCAML_IS_BUILT): ocaml/Makefile.config | _build touch $@ # CONFIGURATION FILES -solo5.conf: solo5.conf.in - sed -e 's!@@PREFIX@@!$(MAKECONF_PREFIX)!' \ - solo5.conf.in > $@ +_build/solo5.conf: gen_solo5_conf.sh $(OCAML_IS_BUILT) + SYSROOT="$(MAKECONF_SYSROOT)" ./gen_solo5_conf.sh > $@ # COMMANDS install: all diff --git a/gen_solo5_conf.sh b/gen_solo5_conf.sh new file mode 100755 index 00000000..53d5f234 --- /dev/null +++ b/gen_solo5_conf.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +checkopt() { + if test -x ocaml/"$1".opt; then + printf '.opt' + else + printf '.byte' + fi +} + +cat << EOF +path(solo5) = "$SYSROOT/lib" +destdir(solo5) = "$SYSROOT/lib" +stdlib(solo5) = "$SYSROOT/lib/ocaml" +ocamlopt(solo5) = "$SYSROOT/bin/ocamlopt$(checkopt ocamlopt)" +ocamlc(solo5) = "$SYSROOT/bin/ocamlc$(checkopt ocamlc)" +ocamlmklib(solo5) = "$SYSROOT/bin/ocamlmklib" +ocamldep(solo5) = "$SYSROOT/bin/ocamldep$(checkopt tools/ocamldep)" +ocamlcp(solo5) = "$SYSROOT/bin/ocamlcp" +EOF diff --git a/solo5.conf.in b/solo5.conf.in deleted file mode 100644 index 4ed8ef53..00000000 --- a/solo5.conf.in +++ /dev/null @@ -1,8 +0,0 @@ -path(solo5) = "@@PREFIX@@/solo5-sysroot/lib" -destdir(solo5) = "@@PREFIX@@/solo5-sysroot/lib" -stdlib(solo5) = "@@PREFIX@@/solo5-sysroot/lib/ocaml" -ocamlopt(solo5) = "@@PREFIX@@/solo5-sysroot/bin/ocamlopt" -ocamlc(solo5) = "@@PREFIX@@/solo5-sysroot/bin/ocamlc" -ocamlmklib(solo5) = "@@PREFIX@@/solo5-sysroot/bin/ocamlmklib" -ocamldep(solo5) = "@@PREFIX@@/solo5-sysroot/bin/ocamldep" -ocamlcp(solo5) = "@@PREFIX@@/solo5-sysroot/bin/ocamlcp" From dbcf5b4c404d4924a07b827e54bf5d1fec607454 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 14:02:21 +0200 Subject: [PATCH 67/92] Update {,dist}clean targets Instead of removing the `ocaml` directory, invoke the `clean` and `distclean` rules of the compiler's Makefile, to play nicer with work done in there --- Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 776eab72..4ca2e6bc 100644 --- a/Makefile +++ b/Makefile @@ -125,12 +125,14 @@ install: all MAKE=$(MAKE) PREFIX=$(MAKECONF_PREFIX) ./install.sh clean: - $(RM) -r ocaml/ - $(RM) solo5.conf + $(RM) -rf _build $(MAKE) -C openlibm clean - $(MAKE) -C nolibc \ - "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" \ - clean + $(MAKE) -C nolibc clean FREESTANDING_CFLAGS=_ + if [ -d ocaml ] ; then $(MAKE) -C ocaml clean ; fi + distclean: clean - rm Makeconf + $(RM) -f Makeconf +# Don't remove the ocaml directory itself, to play nicer with +# development in there + if [ -d ocaml ] ; then $(MAKE) -C ocaml distclean ; fi From 19a53b9e6664f01517cf7c90a6e44d83df8d3481 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 14:05:58 +0200 Subject: [PATCH 68/92] Update the dependencies of the `all` target Update the dependencies of the `all` target to cover everything that needs to be installed Move it to the end, to use variables Create a `default` target to make sure `all` is still the default target --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4ca2e6bc..98aa14ab 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ include Makeconf -all: openlibm/libopenlibm.a nolibc/libnolibc.a ocaml solo5.conf +# The `all` target is moved to the end to use variables in its dependencies +default: all TOP=$(abspath .) @@ -136,3 +137,7 @@ distclean: clean # Don't remove the ocaml directory itself, to play nicer with # development in there if [ -d ocaml ] ; then $(MAKE) -C ocaml distclean ; fi + +all: $(LIBS) $(OCAML_IS_BUILT) \ + _build/solo5.conf _build/empty-META \ + $(TOOLCHAIN_FINAL) From 8138dbe6135e288e19744b29ff52a80122934163 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 14:06:22 +0200 Subject: [PATCH 69/92] Add a `test` rule --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 98aa14ab..24cc3413 100644 --- a/Makefile +++ b/Makefile @@ -141,3 +141,8 @@ distclean: clean all: $(LIBS) $(OCAML_IS_BUILT) \ _build/solo5.conf _build/empty-META \ $(TOOLCHAIN_FINAL) + +test: + $(MAKE) -C nolibc test-headers \ + "CC=$(MAKECONF_TOOLCHAIN)-cc" \ + "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" From 1eb5f34d3f9ee00037836389ae0c4ef550cb047c Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 5 Apr 2024 12:07:12 +0200 Subject: [PATCH 70/92] Split up the declaration of phoniness of targets `ocaml` is no longer a phony target Follow the OCaml's usage of declaring `.PHONY`-ness of targets at the place those targets are defined, to make maintenance easier --- Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 24cc3413..c3f2ecef 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ -.PHONY: all clean install distclean ocaml - include Makeconf # The `all` target is moved to the end to use variables in its dependencies +.PHONY: default default: all TOP=$(abspath .) @@ -122,26 +121,30 @@ _build/solo5.conf: gen_solo5_conf.sh $(OCAML_IS_BUILT) SYSROOT="$(MAKECONF_SYSROOT)" ./gen_solo5_conf.sh > $@ # COMMANDS +.PHONY: install install: all MAKE=$(MAKE) PREFIX=$(MAKECONF_PREFIX) ./install.sh +.PHONY: clean clean: $(RM) -rf _build $(MAKE) -C openlibm clean $(MAKE) -C nolibc clean FREESTANDING_CFLAGS=_ if [ -d ocaml ] ; then $(MAKE) -C ocaml clean ; fi - +.PHONY: distclean distclean: clean $(RM) -f Makeconf # Don't remove the ocaml directory itself, to play nicer with # development in there if [ -d ocaml ] ; then $(MAKE) -C ocaml distclean ; fi +.PHONY: all all: $(LIBS) $(OCAML_IS_BUILT) \ _build/solo5.conf _build/empty-META \ $(TOOLCHAIN_FINAL) +.PHONY: test test: $(MAKE) -C nolibc test-headers \ "CC=$(MAKECONF_TOOLCHAIN)-cc" \ From 73169a704224ddf81773d1a5d3a88b4866ff8015 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 14:04:53 +0200 Subject: [PATCH 71/92] Add a rule to build an empty file to use as `META` --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index c3f2ecef..c85dc234 100644 --- a/Makefile +++ b/Makefile @@ -120,6 +120,9 @@ $(OCAML_IS_BUILT): ocaml/Makefile.config | _build _build/solo5.conf: gen_solo5_conf.sh $(OCAML_IS_BUILT) SYSROOT="$(MAKECONF_SYSROOT)" ./gen_solo5_conf.sh > $@ +_build/empty-META: | _build + touch $@ + # COMMANDS .PHONY: install install: all From 3f9e11dd17c3c6fd4d03a9d21cd4005dbedf4124 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Thu, 4 Apr 2024 14:03:36 +0200 Subject: [PATCH 72/92] Generate an OPAM .install file Add two scripts to create an .install file: - `gen_ocaml_install.sh` drives (bends...) OCaml's `make install` in order to generate two subfiles, namely `_build/ocaml.install.lib{,exec}`, containing the lines to install the compiler itself, into the `lib` and `libexec` sections - `gen_dot_install.sh` generates the complete `.install` file, including the content of the subfiles for the compiler The generated `.install` file diverges from the current installation process in that it tries to follow the standard organisation of the OPAM directory: the OCaml cross-compiler is installed in `%{_:lib}%` (ie `%{prefix}%/lib/ocaml-solo5`) instead of `%{prefix}%/solo5-sysroot`. Note that the paths fed to `configure.sh` must be consistent with that for the installed compiler to work as expected. --- .gitignore | 1 + Makefile | 16 +++++++++ gen_dot_install.sh | 64 ++++++++++++++++++++++++++++++++++ gen_ocaml_install.sh | 82 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100755 gen_dot_install.sh create mode 100755 gen_ocaml_install.sh diff --git a/.gitignore b/.gitignore index 8627418a..4216f050 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ nolibc/test-include/ ocaml/ _build/ /ocaml-src.tar.gz +/*.install diff --git a/Makefile b/Makefile index c85dc234..9295af41 100644 --- a/Makefile +++ b/Makefile @@ -116,6 +116,13 @@ $(OCAML_IS_BUILT): ocaml/Makefile.config | _build cd ocaml && ocamlrun tools/stripdebug ocamlopt ocamlopt.tmp touch $@ +DOT_INSTALL_PREFIX_FOR_OCAML := _build/ocaml.install +DOT_INSTALL_CHUNKS_FOR_OCAML := $(addprefix $(DOT_INSTALL_PREFIX_FOR_OCAML),\ + .lib .libexec) +$(DOT_INSTALL_CHUNKS_FOR_OCAML): | ocaml/Makefile.config + MAKE="$(MAKE)" ./gen_ocaml_install.sh \ + $(DOT_INSTALL_PREFIX_FOR_OCAML) ocaml $(MAKECONF_SYSROOT) + # CONFIGURATION FILES _build/solo5.conf: gen_solo5_conf.sh $(OCAML_IS_BUILT) SYSROOT="$(MAKECONF_SYSROOT)" ./gen_solo5_conf.sh > $@ @@ -123,6 +130,14 @@ _build/solo5.conf: gen_solo5_conf.sh $(OCAML_IS_BUILT) _build/empty-META: | _build touch $@ +# INSTALL +PACKAGES := $(basename $(wildcard *.opam)) +INSTALL_FILES := $(foreach pkg,$(PACKAGES),$(pkg).install) + +$(INSTALL_FILES): $(TOOLCHAIN_FINAL) $(DOT_INSTALL_CHUNKS_FOR_OCAML) + ./gen_dot_install.sh $(DOT_INSTALL_PREFIX_FOR_OCAML) $(TOOLCHAIN_FINAL)\ + > $@ + # COMMANDS .PHONY: install install: all @@ -134,6 +149,7 @@ clean: $(MAKE) -C openlibm clean $(MAKE) -C nolibc clean FREESTANDING_CFLAGS=_ if [ -d ocaml ] ; then $(MAKE) -C ocaml clean ; fi + $(RM) -f $(INSTALL_FILES) .PHONY: distclean distclean: clean diff --git a/gen_dot_install.sh b/gen_dot_install.sh new file mode 100755 index 00000000..ea228e29 --- /dev/null +++ b/gen_dot_install.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +if [ ! -e "$1.lib" ] || [ ! -e "$1.libexec" ]; then + echo "Usage: $0 " + echo "The *.install.lib and *.install.libexec for OCaml must be available." + exit 1 +fi + +prefix_for_ocaml_chunks="$1" +shift + +install_file() { + # install_file [dest] + if [ -z "$2" ]; then + printf ' "%s"\n' "$1" + else + printf ' "%s" { "%s" }\n' "$1" "$2" + fi +} + +walk_tree() { + # walk_tree [extension] + # where *prefix are not empty + for f in "$1"/*"$3"; do + base="${f##*/}" + if [ -d "$f" ]; then + walk_tree "$f" "$2/$base" "$3" + else + install_file "$f" "$2/$base" + fi + done +} + +main() { + printf '%s: [\n' bin + for f in "$@"; do + install_file "$f" + done + printf ']\n' + + printf '%s: [\n' lib_root + install_file _build/solo5.conf findlib.conf.d/solo5.conf + printf ']\n' + + printf '%s: [\n' libexec + cat "$prefix_for_ocaml_chunks".libexec + printf ']\n' + + printf '%s: [\n' lib + cat "$prefix_for_ocaml_chunks".lib + walk_tree nolibc/include include + install_file nolibc/libnolibc.a lib/libnolibc.a + walk_tree openlibm/include include + walk_tree openlibm/src include .h + install_file openlibm/libopenlibm.a lib/libopenlibm.a + # dummy packages + for pkg in nolibc threads is_solo5; do + install_file _build/empty-META lib/$pkg/META + done + printf ']\n' +} + +# The only arguments left are the toolchain tools +main "$@" diff --git a/gen_ocaml_install.sh b/gen_ocaml_install.sh new file mode 100755 index 00000000..dd12d624 --- /dev/null +++ b/gen_ocaml_install.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +main() { + PREFIXINSTALLFILE="$1" + OCAMLDIR="$2" + PREFIX="$3" + + if [ ! -d "$OCAMLDIR" ] || [ -z "$PREFIX" ]; then + echo "Usage: $0 " + exit 1 + fi + + OCAMLDIR="$(realpath "$OCAMLDIR")" + INSTALLDIR="$(mktemp -d "$OCAMLDIR/tmp.XXXXXX")" + ME="$(realpath "$0")" + ln -s "$ME" "$INSTALLDIR/fake_install" + ln -s "$ME" "$INSTALLDIR/rm" + ln -s "$ME" "$INSTALLDIR/ln" + ln -s "$ME" "$INSTALLDIR/fake_ocamlrun" + + export PATH="$INSTALLDIR:$PATH" + export GEN_OCAML_INSTALL_BASEDIR="$OCAMLDIR" + export GEN_OCAML_INSTALL_INSTALLDIR="$INSTALLDIR" + export GEN_OCAML_INSTALL_PREFIX="$PREFIX" + ${MAKE:-make} -C "$OCAMLDIR" \ + DESTDIR="$INSTALLDIR" \ + INSTALL_PROG="fake_install libexec" \ + INSTALL_DATA="fake_install lib" \ + OCAMLRUN=fake_ocamlrun \ + install + + mv "$INSTALLDIR/install.lib" "$PREFIXINSTALLFILE.lib" + mv "$INSTALLDIR/install.libexec" "$PREFIXINSTALLFILE.libexec" +} + +install() { + # This argument massaging is bash-only, I think making it more portable would + # be more verbose + destdir="${!#}" # the last argument + section="$1" + set -- "${@:2:$(($# - 2))}" # all but the first and last arguments + todrop="$GEN_OCAML_INSTALL_INSTALLDIR$GEN_OCAML_INSTALL_PREFIX/" + destsubdir="${destdir:${#todrop}}" + todrop="$GEN_OCAML_INSTALL_BASEDIR/" + srcsubdir="${PWD:${#todrop}}" + # if not empty, had a trailing `/` + srcsubdir="${srcsubdir:+$srcsubdir/}" + if [ ! -d "$destdir" ]; then + # we are installing one binary under a different name + if [ ! "$#" = 1 ]; then + echo Unexpected install command line! + exit 1 + fi + f="${1#./}" + printf ' "?ocaml/%s%s" { "%s" }\n' "$srcsubdir" "$f" "$destsubdir" >> \ + "$GEN_OCAML_INSTALL_INSTALLDIR/install.$section" + else + for f in "$@"; do + printf ' "?ocaml/%s%s" { "%s" }\n' "$srcsubdir" "${f#./}" \ + "$destsubdir/$(basename "$f")" >> \ + "$GEN_OCAML_INSTALL_INSTALLDIR/install.$section" + done + fi +} + +case "$0" in + *fake_install) + install "$@" + ;; + *rm) + echo "Dummy rm $*" + ;; + *ln) + echo "Dummy ln $*" + ;; + *fake_ocamlrun) + echo "Dummy ocamlrun $*" + ;; + *) + main "$@" + ;; +esac From 039aa27ea84c568c803f47c5332d3a8c388a36d5 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 29 Mar 2024 17:15:39 +0100 Subject: [PATCH 73/92] Use opam-installer for the install target In the standard use case, namely installation through OPAM, this target is no longer necessary, since a `.install` file is generated so that OPAM does the installation per se internally Remove install.sh --- Makefile | 5 +++-- install.sh | 32 -------------------------------- 2 files changed, 3 insertions(+), 34 deletions(-) delete mode 100755 install.sh diff --git a/Makefile b/Makefile index 9295af41..7d5e84c8 100644 --- a/Makefile +++ b/Makefile @@ -139,9 +139,10 @@ $(INSTALL_FILES): $(TOOLCHAIN_FINAL) $(DOT_INSTALL_CHUNKS_FOR_OCAML) > $@ # COMMANDS +PACKAGE := ocaml-solo5 .PHONY: install -install: all - MAKE=$(MAKE) PREFIX=$(MAKECONF_PREFIX) ./install.sh +install: $(PACKAGE).install + opam-installer --prefix=$(MAKECONF_PREFIX) $< .PHONY: clean clean: diff --git a/install.sh b/install.sh deleted file mode 100755 index 41d043c9..00000000 --- a/install.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -ex - -DESTINC="${PREFIX}/solo5-sysroot/include/nolibc" -DESTLIB="${PREFIX}/solo5-sysroot/lib/nolibc" -SYSROOT="${PREFIX}/solo5-sysroot" -mkdir -p "${DESTINC}" "${DESTLIB}" "${SYSROOT}" - -# nolibc -cp -r nolibc/include/* "${DESTINC}" -cp nolibc/libnolibc.a "${DESTLIB}" - -# Openlibm -cp -r openlibm/include/* "${DESTINC}" -cp openlibm/src/*h "${DESTINC}" -cp openlibm/libopenlibm.a "${DESTLIB}" - -# OCaml -${MAKE} -C ocaml install - -# META: ocamlfind and other build utilities test for existance ${DESTLIB}/META -# when figuring out whether a library is installed -touch "${DESTLIB}/META" - -# findlib -mkdir -p "${PREFIX}/lib/findlib.conf.d" -cp solo5.conf "${PREFIX}/lib/findlib.conf.d/solo5.conf" - -# dummy packages -mkdir -p "${SYSROOT}/lib/threads" -touch "${SYSROOT}/lib/threads/META" # for ocamlfind -mkdir -p "${SYSROOT}/lib/is_solo5" -touch "${SYSROOT}/lib/is_solo5/META" From 87cfda7c94fadaaee58281fc513b06ea9dc118bb Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 26 Mar 2024 19:15:18 +0100 Subject: [PATCH 74/92] Drop ocaml-option-nnp, not available in OCaml 5+, from .opam --- ocaml-solo5-cross-aarch64.opam | 1 - ocaml-solo5.opam | 1 - 2 files changed, 2 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index 1b589bfe..d7eb74e3 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -12,7 +12,6 @@ build: [ "--target=aarch64-solo5-none-static" "--ocaml-configure-option=--disable-flat-float-array" {ocaml-option-no-flat-float-array:installed} "--ocaml-configure-option=--enable-flambda" {ocaml-option-flambda:installed} - "--ocaml-configure-option=--disable-naked-pointers" {ocaml-option-nnp:installed} ] [make "-j%{jobs}%"] ] diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index 480f39e5..928aa28d 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -13,7 +13,6 @@ build: [ "--target=aarch64-solo5-none-static" { arch = "arm64" } "--ocaml-configure-option=--disable-flat-float-array" {ocaml-option-no-flat-float-array:installed} "--ocaml-configure-option=--enable-flambda" {ocaml-option-flambda:installed} - "--ocaml-configure-option=--disable-naked-pointers" {ocaml-option-nnp:installed} ] [make "-j%{jobs}%"] ] From 4c5a2f1ba375a48465759237a8eb54634c9b1e2a Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 5 Apr 2024 10:19:31 +0200 Subject: [PATCH 75/92] Update the rules and dependencies of the OPAM packages --- ocaml-solo5-cross-aarch64.opam | 13 +++++++++---- ocaml-solo5.opam | 10 +++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index d7eb74e3..56880de3 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -9,20 +9,25 @@ dev-repo: "git+https://github.com/mirage/ocaml-solo5.git" build: [ ["./configure.sh" "--prefix=%{prefix}%" + "--sysroot=%{_:lib}%" "--target=aarch64-solo5-none-static" "--ocaml-configure-option=--disable-flat-float-array" {ocaml-option-no-flat-float-array:installed} "--ocaml-configure-option=--enable-flambda" {ocaml-option-flambda:installed} ] [make "-j%{jobs}%"] + [make "%{name}%.install"] +] +run-test: [ + [make "test"] ] -install: [make "install" ] depends: [ - "conf-which" {build} + "conf-git" {build} # to patch the compiler sources + "conf-pkg-config" {build} # to detect how to link with zstd "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} "ocaml" {>= "5.0" & < "5.2"} - "solo5" {>= "0.8.0"} - "solo5-cross-aarch64" {>= "0.8.0" } + "solo5" {>= "0.9.0"} + "solo5-cross-aarch64" {>= "0.9.0" } ] conflicts: [ "ocaml-solo5" diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index 928aa28d..e14f6f8d 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -15,14 +15,18 @@ build: [ "--ocaml-configure-option=--enable-flambda" {ocaml-option-flambda:installed} ] [make "-j%{jobs}%"] + [make "%{name}%.install"] +] +run-test: [ + [make "test"] ] -install: [make "install" ] depends: [ - "conf-which" {build} + "conf-git" {build} # to patch the compiler sources + "conf-pkg-config" {build} # to detect how to link with zstd "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} "ocaml" {>= "5.0" & < "5.2"} - "solo5" {>= "0.8.0"} + "solo5" {>= "0.9.0"} ] conflicts: [ "sexplib" {= "v0.9.0"} From e12bfe91968ff7cbfdead88688099c2fe1779a87 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 5 Apr 2024 10:20:25 +0200 Subject: [PATCH 76/92] OPAM package: Depend on the 5.2.1 OCaml compiler --- ocaml-solo5-cross-aarch64.opam | 2 +- ocaml-solo5.opam | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ocaml-solo5-cross-aarch64.opam b/ocaml-solo5-cross-aarch64.opam index 56880de3..2e8b9e81 100644 --- a/ocaml-solo5-cross-aarch64.opam +++ b/ocaml-solo5-cross-aarch64.opam @@ -25,7 +25,7 @@ depends: [ "conf-pkg-config" {build} # to detect how to link with zstd "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "5.0" & < "5.2"} + "ocaml" {= "5.2.1"} "solo5" {>= "0.9.0"} "solo5-cross-aarch64" {>= "0.9.0" } ] diff --git a/ocaml-solo5.opam b/ocaml-solo5.opam index e14f6f8d..375499df 100644 --- a/ocaml-solo5.opam +++ b/ocaml-solo5.opam @@ -25,7 +25,7 @@ depends: [ "conf-pkg-config" {build} # to detect how to link with zstd "ocamlfind" {build} # needed by dune context (for tests) "ocaml-src" {build} - "ocaml" {>= "5.0" & < "5.2"} + "ocaml" {= "5.2.1"} "solo5" {>= "0.9.0"} ] conflicts: [ From 5d6265f20f78b45818fca432286848d014c833d7 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 26 Nov 2024 12:31:55 +0100 Subject: [PATCH 77/92] Add patches for OCaml 5.2.1 --- ...sues-with-preprocessor-directives-13.patch | 49 +++ ...and-use-CC-.-_FOR_BUILD-to-build-sak.patch | 311 ++++++++++++++++++ ...ad-of-host-to-detect-the-C-toolchain.patch | 112 +++++++ ...ad-of-host-when-relevant-in-configur.patch | 83 +++++ ...he-strip-command-detected-by-libtool.patch | 42 +++ ...-Strip-tmpheader.exe-also-on-Windows.patch | 32 ++ ...-target-OS-to-configure-freestanding.patch | 65 ++++ .../5.2.1/0008-Define-OS-type-to-None.patch | 38 +++ ...-targets-to-supported-configurations.patch | 40 +++ ...onfigured-and-the-installed-OCaml-ar.patch | 46 +++ ...the-target-pkg-config-to-detect-zstd.patch | 44 +++ ...le.cross-for-recipes-to-build-a-cros.patch | 122 +++++++ patches/5.2.1/0013-Set-Max_domains-to-1.patch | 35 ++ ...n-executable-on-freestanding-targets.patch | 53 +++ 14 files changed, 1072 insertions(+) create mode 100644 patches/5.2.1/0001-Fix-two-small-issues-with-preprocessor-directives-13.patch create mode 100644 patches/5.2.1/0002-Detect-and-use-CC-.-_FOR_BUILD-to-build-sak.patch create mode 100644 patches/5.2.1/0003-Use-target-instead-of-host-to-detect-the-C-toolchain.patch create mode 100644 patches/5.2.1/0004-Use-target-instead-of-host-when-relevant-in-configur.patch create mode 100644 patches/5.2.1/0005-Use-the-strip-command-detected-by-libtool.patch create mode 100644 patches/5.2.1/0006-Strip-tmpheader.exe-also-on-Windows.patch create mode 100644 patches/5.2.1/0007-Allow-ocaml-as-a-target-OS-to-configure-freestanding.patch create mode 100644 patches/5.2.1/0008-Define-OS-type-to-None.patch create mode 100644 patches/5.2.1/0009-Add-freestanding-targets-to-supported-configurations.patch create mode 100644 patches/5.2.1/0010-Check-that-the-configured-and-the-installed-OCaml-ar.patch create mode 100644 patches/5.2.1/0011-Use-the-target-pkg-config-to-detect-zstd.patch create mode 100644 patches/5.2.1/0012-WIP-Add-a-Makefile.cross-for-recipes-to-build-a-cros.patch create mode 100644 patches/5.2.1/0013-Set-Max_domains-to-1.patch create mode 100644 patches/5.2.1/0014-Set-stack-as-non-executable-on-freestanding-targets.patch diff --git a/patches/5.2.1/0001-Fix-two-small-issues-with-preprocessor-directives-13.patch b/patches/5.2.1/0001-Fix-two-small-issues-with-preprocessor-directives-13.patch new file mode 100644 index 00000000..6895757f --- /dev/null +++ b/patches/5.2.1/0001-Fix-two-small-issues-with-preprocessor-directives-13.patch @@ -0,0 +1,49 @@ +From 189d0adbdcbc480fe3c9c79abf4b3f1df584e0c1 Mon Sep 17 00:00:00 2001 +From: shym +Date: Thu, 4 Jul 2024 18:01:17 +0200 +Subject: [PATCH 01/14] Fix two small issues with preprocessor directives + (#13281) + +* Add missing `defined` in preprocessor test + +When `HAS_CLOCK_GETTIME_NSEC_NP` is not defined, +`#elif HAS_CLOCK_GETTIME_NSEC_NP` triggers a warning + +* Include `caml/config.h` before `HAS_GETTIMEOFDAY` is tested + +Also remove a duplicate `errno.h` +--- + runtime/unix.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/runtime/unix.c b/runtime/unix.c +index b5fd4de17b..c0677e09ac 100644 +--- a/runtime/unix.c ++++ b/runtime/unix.c +@@ -27,13 +27,12 @@ + #include + #include + #include ++#include "caml/config.h" + #ifdef HAS_GETTIMEOFDAY + #include + #endif + #include + #include +-#include +-#include "caml/config.h" + #if defined(SUPPORT_DYNAMIC_LINKING) && !defined(BUILDING_LIBCAMLRUNS) + #define WITH_DYNAMIC_LINKING + #ifdef __CYGWIN__ +@@ -47,7 +46,7 @@ + #endif + #ifdef HAS_POSIX_MONOTONIC_CLOCK + #include +-#elif HAS_CLOCK_GETTIME_NSEC_NP ++#elif defined(HAS_CLOCK_GETTIME_NSEC_NP) + #include + #endif + #ifdef HAS_DIRENT +-- +2.45.2 + diff --git a/patches/5.2.1/0002-Detect-and-use-CC-.-_FOR_BUILD-to-build-sak.patch b/patches/5.2.1/0002-Detect-and-use-CC-.-_FOR_BUILD-to-build-sak.patch new file mode 100644 index 00000000..91ede646 --- /dev/null +++ b/patches/5.2.1/0002-Detect-and-use-CC-.-_FOR_BUILD-to-build-sak.patch @@ -0,0 +1,311 @@ +From acd2f9c4ae0ee5dd550796b547e781794eb9b58c Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Wed, 21 Feb 2024 18:47:12 +0100 +Subject: [PATCH 02/14] Detect and use {CC,...}_FOR_BUILD to build sak + +--- + Makefile | 9 +- + Makefile.config.in | 4 + + aclocal.m4 | 1 + + build-aux/ax_prog_cc_for_build.m4 | 155 ++++++++++++++++++++++++++++++ + configure | Bin 647326 -> 682393 bytes + configure.ac | 10 +- + 6 files changed, 172 insertions(+), 7 deletions(-) + create mode 100644 build-aux/ax_prog_cc_for_build.m4 + +diff --git a/Makefile b/Makefile +index 71d41cd2d6..df191af79c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1284,11 +1284,10 @@ runtime/caml/jumptbl.h : runtime/caml/instruct.h + sed -n -e '/^ /s/ \([A-Z]\)/ \&\&lbl_\1/gp' \ + -e '/^}/q' > $@ + +-# These are provided as a temporary shim to allow cross-compilation systems +-# to supply a host C compiler and different flags and a linking macro. +-SAK_CC ?= $(CC) +-SAK_CFLAGS ?= $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) +-SAK_LINK ?= $(MKEXE_VIA_CC) ++SAK_CC ?= $(CC_FOR_BUILD) ++SAK_CFLAGS ?=\ ++ $(OC_CFLAGS) $(CFLAGS_FOR_BUILD) $(OC_CPPFLAGS) $(CPPFLAGS_FOR_BUILD) ++SAK_LINK ?= $(SAK_CC) $(SAK_CFLAGS) $(OC_EXE_LDFLAGS) $(OUTPUTEXE)$(1) $(2) + + $(SAK): runtime/sak.$(O) + $(V_MKEXE)$(call SAK_LINK,$@,$^) +diff --git a/Makefile.config.in b/Makefile.config.in +index 559738f6ed..4243bebad9 100644 +--- a/Makefile.config.in ++++ b/Makefile.config.in +@@ -65,11 +65,13 @@ LIBTOOL = $(TOP_BUILDDIR)/libtool + ### Which C compiler to use + TOOLPREF=@ac_tool_prefix@ + CC=@CC@ ++CC_FOR_BUILD=@CC_FOR_BUILD@ + + CC_HAS_DEBUG_PREFIX_MAP=@cc_has_debug_prefix_map@ + AS_HAS_DEBUG_PREFIX_MAP=@as_has_debug_prefix_map@ + + LDFLAGS?=@LDFLAGS@ ++LDFLAGS_FOR_BUILD=@LDFLAGS_FOR_BUILD@ + + ### How to invoke the C preprocessor through the C compiler + CPP=@CPP@ +@@ -160,7 +162,9 @@ UNIX_OR_WIN32=@unix_or_win32@ + INSTALL_SOURCE_ARTIFACTS=@install_source_artifacts@ + + CFLAGS=@CFLAGS@ ++CFLAGS_FOR_BUILD=@CFLAGS_FOR_BUILD@ + CPPFLAGS=@CPPFLAGS@ ++CPPFLAGS_FOR_BUILD=@CPPFLAGS_FOR_BUILD@ + OCAMLC_CFLAGS=@ocamlc_cflags@ + + OCAMLC_CPPFLAGS=@ocamlc_cppflags@ +diff --git a/aclocal.m4 b/aclocal.m4 +index cb73385dda..d2e58a45f6 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -30,6 +30,7 @@ m4_include([build-aux/ax_check_compile_flag.m4]) + + # Macros from the autoconf macro archive + m4_include([build-aux/ax_func_which_gethostbyname_r.m4]) ++m4_include([build-aux/ax_prog_cc_for_build.m4]) + m4_include([build-aux/ax_pthread.m4]) + + # OCaml version +diff --git a/build-aux/ax_prog_cc_for_build.m4 b/build-aux/ax_prog_cc_for_build.m4 +new file mode 100644 +index 0000000000..1db8d73f96 +--- /dev/null ++++ b/build-aux/ax_prog_cc_for_build.m4 +@@ -0,0 +1,155 @@ ++# =========================================================================== ++# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_PROG_CC_FOR_BUILD ++# ++# DESCRIPTION ++# ++# This macro searches for a C compiler that generates native executables, ++# that is a C compiler that surely is not a cross-compiler. This can be ++# useful if you have to generate source code at compile-time like for ++# example GCC does. ++# ++# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything ++# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). ++# The value of these variables can be overridden by the user by specifying ++# a compiler with an environment variable (like you do for standard CC). ++# ++# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object ++# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if ++# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are ++# substituted in the Makefile. ++# ++# LICENSE ++# ++# Copyright (c) 2008 Paolo Bonzini ++# ++# Copying and distribution of this file, with or without modification, are ++# permitted in any medium without royalty provided the copyright notice ++# and this notice are preserved. This file is offered as-is, without any ++# warranty. ++ ++#serial 21 ++ ++AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) ++AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_PROG_CPP])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++ ++dnl Use the standard macros, but make them use other variable names ++dnl ++pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl ++pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl ++pushdef([ac_cv_prog_cc_c99], ac_cv_build_prog_cc_c99)dnl ++pushdef([ac_cv_prog_cc_c11], ac_cv_build_prog_cc_c11)dnl ++pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl ++pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl ++pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl ++pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl ++pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl ++pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl ++pushdef([ac_cv_objext], ac_cv_build_objext)dnl ++pushdef([ac_exeext], ac_build_exeext)dnl ++pushdef([ac_objext], ac_build_objext)dnl ++pushdef([CC], CC_FOR_BUILD)dnl ++pushdef([CPP], CPP_FOR_BUILD)dnl ++pushdef([GCC], GCC_FOR_BUILD)dnl ++pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl ++pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl ++pushdef([EXEEXT], BUILD_EXEEXT)dnl ++pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl ++pushdef([OBJEXT], BUILD_OBJEXT)dnl ++pushdef([host], build)dnl ++pushdef([host_alias], build_alias)dnl ++pushdef([host_cpu], build_cpu)dnl ++pushdef([host_vendor], build_vendor)dnl ++pushdef([host_os], build_os)dnl ++pushdef([ac_cv_host], ac_cv_build)dnl ++pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl ++pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl ++pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl ++pushdef([ac_cv_host_os], ac_cv_build_os)dnl ++pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl ++pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl ++pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl ++pushdef([cross_compiling], cross_compiling_build)dnl ++ ++cross_compiling_build=no ++ ++ac_build_tool_prefix= ++AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"], ++ [test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"]) ++ ++AC_LANG_PUSH([C]) ++ ++dnl The pushdef([ac_cv_c_compiler_gnu], ...) currently does not cover ++dnl the use of this variable in _AC_LANG_COMPILER_GNU called by ++dnl AC_PROG_CC. Unset this cache variable temporarily as a workaround. ++was_set_c_compiler_gnu=${[ac_cv_c_compiler_gnu]+y} ++AS_IF([test ${was_set_c_compiler_gnu}], ++ [saved_c_compiler_gnu=$[ac_cv_c_compiler_gnu] ++ AS_UNSET([[ac_cv_c_compiler_gnu]])]) ++ ++AC_PROG_CC ++ ++dnl Restore ac_cv_c_compiler_gnu ++AS_IF([test ${was_set_c_compiler_gnu}], ++ [[ac_cv_c_compiler_gnu]=$[saved_c_compiler_gnu]]) ++ ++_AC_COMPILER_EXEEXT ++_AC_COMPILER_OBJEXT ++AC_PROG_CPP ++ ++dnl Restore the old definitions ++dnl ++popdef([cross_compiling])dnl ++popdef([am_cv_prog_cc_c_o])dnl ++popdef([am_cv_CC_dependencies_compiler_type])dnl ++popdef([ac_tool_prefix])dnl ++popdef([ac_cv_host_os])dnl ++popdef([ac_cv_host_vendor])dnl ++popdef([ac_cv_host_cpu])dnl ++popdef([ac_cv_host_alias])dnl ++popdef([ac_cv_host])dnl ++popdef([host_os])dnl ++popdef([host_vendor])dnl ++popdef([host_cpu])dnl ++popdef([host_alias])dnl ++popdef([host])dnl ++popdef([OBJEXT])dnl ++popdef([LDFLAGS])dnl ++popdef([EXEEXT])dnl ++popdef([CPPFLAGS])dnl ++popdef([CFLAGS])dnl ++popdef([GCC])dnl ++popdef([CPP])dnl ++popdef([CC])dnl ++popdef([ac_objext])dnl ++popdef([ac_exeext])dnl ++popdef([ac_cv_objext])dnl ++popdef([ac_cv_exeext])dnl ++popdef([ac_cv_c_compiler_gnu])dnl ++popdef([ac_cv_prog_cc_g])dnl ++popdef([ac_cv_prog_cc_cross])dnl ++popdef([ac_cv_prog_cc_works])dnl ++popdef([ac_cv_prog_cc_c89])dnl ++popdef([ac_cv_prog_gcc])dnl ++popdef([ac_cv_prog_CPP])dnl ++ ++dnl restore global variables ac_ext, ac_cpp, ac_compile, ++dnl ac_link, ac_compiler_gnu (dependant on the current ++dnl language after popping): ++AC_LANG_POP([C]) ++ ++dnl Finally, set Makefile variables ++dnl ++AC_SUBST(BUILD_EXEEXT)dnl ++AC_SUBST(BUILD_OBJEXT)dnl ++AC_SUBST([CFLAGS_FOR_BUILD])dnl ++AC_SUBST([CPPFLAGS_FOR_BUILD])dnl ++AC_SUBST([LDFLAGS_FOR_BUILD])dnl ++]) +diff --git a/configure b/configure +index 49d5bff6495b2f38d91d97ec777a4212e3c23677..9f16ca87352a88b5e995631c15fd8914f6b2ebfc 100755 +GIT binary patch +delta 6754 +zcmds5eN0r@70*4x8{mn2L`L~qc=H?>6lV~20WBRBXVBG91-ET%WBL}xfn~)RWQLV3 +zK{Ph8G;Lv*T~2gUm$peawcBQClTMp#7frfd~-*CgKtYi-PWh1EjxEfo4>TJ!N+?W +z8xy+B9SWzkbMyB4-CyKYqJDS1OwiektY*LDk4RoG(`6)%4(vEKu!GPa=x?EaQgmPk +zCq?@O`mwwor=!&CUFGDJ0n>(*L8ULokf4OZqV;M_3A)QXS|_Y>;&smIz@rCKDhu}p +zA_0G-J=i8ho(TwEArcC8_@8NR4+^cJE&+dkm=p|WZnXCQcfOYH_Kv-xu%V>7wvXp| +ze^)3Rmi(dpo$Vb|w4@Asf+3!#uqlKjuOoGK1zOvCJbZhr5DA1Mf-5M94pkOUw-XdT +zM=?>R_^Euu9F5N<@_~-T=~8n?dvjPc30Xjf%Ip#`R0Vl0`hg0LM1yh48mNi|D5mT& +z3NAmLVLHC~WDMJsh&p=bXY13E4L3g**el`eq@~y@8*s0HbCZ_r +zR8OtY9i$7WB-Hjjn(%T8y!i21B52L#+u%d#9QnLPpEyTO@%l;Q_umC?8f!TC!Utf> +zWqUj#V_DI;H_4Ytj%mC%W+X^1kkMLQzDG76|8w+ih1!h%DR!vJEz`x}l@{>w4Bb3V +za#*^5oP_Z7QA>Wc&eY%&Yh{lSR4=H>6?&NMH~6q=ng}?3kxZFkz|0#Yh3%wB-ssD*=nipMRUe0kFG9Cw1hao4yR_!c2`GQcu=@lR>02cTt?kscg#)x@ +zU{(Q{=X~*nNn&Hc{Lv&4b(>s{mnX?Sjo$h$`7z7-pl$M}eL5DMPaef5m#3FT6!YjXS+>N5zVze)Ev!8CrD0uj%x_WG#nV6j;C!8ib?i(unx_xlH^~OgT=(51ubXiUofuV%kt{}1NX +z6lFtIeqK#M%(f~DB_%Yd?G-w^@J2Zq!0&B<^l0%1q~C)7oPZkq$M2HT@Z4`xQ}OQw +zbY#2$-Xf|kzdS~q_`^cDyHdY|p63JM*t@=!)dzo41O;xLvF!OiIoFWGYe~&2XjEm& +zE^xL8yxIC3nk)GOosqEM!n&%Id>pi=EV0cu+=gck5fOU@7${To10`Ja`=vHHO_LK; +z(^4MM)h1%|U*Y7)AZN`mO~RRV)@+=ygLSFCoJSOKw3OIJZgAD;{u)<1vOPH$Px+Fw +z@VE%&Su7_N&Zpwsb*^6F#HW9gY}Xt@XeHF>cn%N!t8_jJ>m2Z6x^Y{0<|AtkcJ8xs +zcIw4 +z_y$Y&mB2<5U5Ha9@R$b7of3FbYkHhexJ2JRKRkBZhoesLvGbcMVVlOkrW8DJ6m9s1 +z3$nD4@07v@cG9P=I7aW6!fRPZg#8s2IN^r3GtJ$YwV$xi53Gg)CWJO5I1N5QiwG1c +zIJO#G+HNkdh9P!0`^$`wP}%^=wX!%Qt~K*OGPDMcvGN#5B-cWaoOUe;Ns${~)3*Ay +z8z!{o%jHn2THKrE_pbJP<#Dw$*BaFxU29aE(uMfR+PEd;R>akQx?&!+sU>9Kx0?u$ +zmnxup0RWCyE(E}bl?wv!mB-@%eD-)8fD2D(0Bly%Q0iCw>(;CFA)!xpF9}Hv>k5tL +zP*@emWqTEDeB=r=o7KBxti#X(O)Pr4hZ>Ahamn{M)LM*5lKj5mk!{JHIFbSB__vvq +z>geu|$+WdtU05wL(dR~f=#)1wmSU>cvB3hG$Hl=ka79Ngu#MQ+xw5wmhUDpL=|LHb +zewqZkEx9aTtTds@^{2o(^}<9?q`)1E)~0J5)!t9cN{9N?xCG2BfFku?9ZZL6wNNOj +z+t&+=D(!KowcF@;I#hy|kVoe-VOW#>i}!BsA$VmO=hNJ#a(!ii*36A*j^L^nOS(pS +z#>QA6$y~emm{}-w19A-89*ndKc(N$Ty@Xi+<(l78rlY|Zt(oOgIrgpCbd76yPu7q0nJy5)&Kwi + +delta 62 +zcmbPvS##b&^$i_<&20YdZ2pWu%ml>DK+Lk8&7U=4`}CCy*!ib_XJZp-XX|GJVs;?r +L*v{6^Ir$a +Date: Thu, 22 Feb 2024 13:37:28 +0100 +Subject: [PATCH 03/14] Use `target` instead of `host` to detect the C + toolchain + +When building a cross-compiler, the runtime will run on the target, not +the host so: +- set `cross_compiling` by comparing `build` to `target` (rather than to + `host`), as this variable will be used later +- use `target` to set up the tool prefix, +- as the libtool configuration will configure a `build` to `host` + toolchain, temporarily assign `host*` values to `target*` values +--- + configure | Bin 682393 -> 682949 bytes + configure.ac | 18 ++++++++++++++++++ + 2 files changed, 18 insertions(+) + +diff --git a/configure b/configure +index 9f16ca87352a88b5e995631c15fd8914f6b2ebfc..f81f4ca213b710395b61b64d1380318d4d80867d 100755 +GIT binary patch +delta 1998 +zcmZ`(drVbz9N+yt?u9D~^12Qaj&QXR!UV#QN5pXGe6e(h`QUQ6_W&nu=Unc&0<{Wr +zD<>GO8vK+s2i9!ONBq(FHF{hNafq|VoH5JU!?YZcjAl&@>UX)nUodan?QEa>`F_s# +z{XIu7rw)#$?*GVC)z(thsCd1qOOc#j-7p+Z{W*{7R<&A5)?AY8bog}L?eKV&8nsz! +zl)b84?N$uQP&KC_`RWv@L<%UJb+W2Ss$or$_8E$caZ;_KDPGyfRI;~L@kvgd1!<~N +zG^u)@>UPb9kerEusLU3Ks(7txjpS1dpVXXepHY#uX0tt(X$v*os<;hBvde};(>>O= +zdymC~8kGz+TUI=jXQ4e9(jmK5*+{q6sB}-8>Ch7ioYsxGab`&J;7ijZcm~ph0aI~I +z5R;zYOxrmuo&>9j|1VP}X|$OmN!hr`N;5`Hp1Ap?(RA&&X)65x1(f-^xhyQ0)1w(= +zxdl8gomu7I0!t;ZJwKOzJrW(hzrdtQTD3?x@xW)&S1G|1oF}<2d&V +z0MXK5amo3CP0_59hg(n2Y;C8)fgU;wM8tvmlQcC0q52Vq>Rs&=oWH^-Tei +z`Kx(_XiAjJlFp9jyr&%H3jX8{)RMsY^aj)_T=pC2JFx&qUPN8uP;w5SB5^=Xub~m4 +z+4KhLS|s8Yp(#LbcB9|LJ!^jSSl{QUUPNX8RSQ>tdmiL-^Wu2knhm89Y%(qoTQV@9d>Y>^JvXM;@S`#FF%xv6}}Qi^R#~c?*uD +zJ1qDuQ4?c-;Zewy#rQ5y3tm<(;iJEM4=x*@sTt_(vb-*3Sw#J&~(LDy}@uZwgq +zmfARQznZR9_EoeIZ=!5!znGe4&ZHKV1x};-!_~d#i~n4@+jl$nbAEl! +z`JVF~ycmiPhdMsdUfdzOcWRvl`E@a~sXAur^)DGsQM1Wt4bGW_g2rMa*xFLRab2v% +z4C+mF(TzrtZWxwYK7Udx$q?Tswdvw&C6w7xo@n?(OBeV4qXlH-TW$Lchgw={pY8z3 +zM_N9^_k$hxW)@pmM$)|1Y*!jd$$GZb@9>kmx3UNBLz}7iY7Z+#o3zm0VVi9iG5#*A +z6uEI`h=%vrEa{E2t4OgdMFL2AtCxN3aYp^}5X&LMPd{SkIN5z8*#btAw~y^|k<^o9 +zfF3(}aFJp6Ma-+wv*gezc2Al!Z@1V!XQyP~UzV?l +z!W!Lsq!!#N2Rd8{i_x`uhTO9NW+}T91#rMa>X(;7HkBhRsj#~Y +zQsiJMjHtQ}Jp+L$3}2{%7*Jk$u^M`(@Zt^7H3giz1y(q~`4V4+r~}NC6FXr46fi7c +zkxztwb@{}lYDkyc_rgI{N#TBoXHX>r +ziHP^IxiXZG3FRX%6yWI;758v4M#$W?1n+1RLs(><6$O{kC$9Blnrth<{uyNRSUDD| +z3fn8NeI`YaJ`>y2?CoyG@6;VNwqZg|rhgkQQBxgx1HV?<@Y|S}_P?o$d$1)ysrve{ +zi&6X0ck$(Ip +zu1*Wu8&SO_YCRZ@lZ#@Vc&Achtpe)Lez!{FqCDmY6Nw>3mT0 +zQM8z8Y*?3T#)7(7*~w>$M;f_LxH9?Y#Ohoo|5*_@mc`wZS8zU?o9U!p9_A0LZEw%z +z5p^x{r}^CDCH0>re4Hl3CnrjIK2v0hp5UugdGRNCvD%d@PxA_LS-6}ZR>~VI_-)li +zOA1JQjvtuZk`oc$rxsOqmh+Xf$?@_le2C`FFORhIoM|f8_?x^nPZhpZ1FzgRz{}A7 +u&lW!p@=K}(wVRsnJ~JiB)J%E(6z`yWe|`NKZk-hCq*})%*Pn5(>G=<2b2Q8V + +diff --git a/configure.ac b/configure.ac +index 2e3a11f60c..0862b381ff 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -288,6 +288,14 @@ AC_CANONICAL_BUILD + AC_CANONICAL_HOST + AC_CANONICAL_TARGET + ++# Override cross_compiling and ac_tool_prefix variables since the C toolchain is ++# used to generate target code when building a cross compiler ++AS_IF([test x"$build" = x"$target"], ++ [cross_compiling=no], ++ [cross_compiling=yes]) ++AS_IF([test -n "$target_alias"], ++ [ac_tool_prefix=$target_alias-]) ++ + # Ensure that AC_CONFIG_LINKS will either create symlinks which are compatible + # with native Windows (i.e. NTFS symlinks, not WSL or Cygwin-emulated ones) or + # use its fallback mechanisms. Native Windows versions of ocamlc/ocamlopt cannot +@@ -594,12 +602,22 @@ AC_CHECK_TOOLS([LD],[ld link]) + # Also, it has been observed that, on some platforms (e.g. msvc) LT_INIT + # alters the CFLAGS variable, so we save its value before calling the macro + # and restore it after the call ++pushdef([host], target)dnl ++pushdef([host_alias], target_alias)dnl ++pushdef([host_cpu], target_cpu)dnl ++pushdef([host_vendor], target_vendor)dnl ++pushdef([host_os], target_os)dnl + old_host_os=$host_os + AS_IF([test x"$host_os" = "xwindows"],[host_os=mingw]) + saved_CFLAGS="$CFLAGS" + LT_INIT + CFLAGS="$saved_CFLAGS" + host_os=$old_host_os ++popdef([host_os])dnl ++popdef([host_vendor])dnl ++popdef([host_cpu])dnl ++popdef([host_alias])dnl ++popdef([host])dnl + + AS_CASE([$host], + [sparc-sun-solaris*], +-- +2.45.2 + diff --git a/patches/5.2.1/0004-Use-target-instead-of-host-when-relevant-in-configur.patch b/patches/5.2.1/0004-Use-target-instead-of-host-when-relevant-in-configur.patch new file mode 100644 index 00000000..4ab437d1 --- /dev/null +++ b/patches/5.2.1/0004-Use-target-instead-of-host-when-relevant-in-configur.patch @@ -0,0 +1,83 @@ +From 7acd97746d8c41a191d5de96b03c915a52bdc142 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Wed, 21 Feb 2024 19:05:44 +0100 +Subject: [PATCH 04/14] Use `target` instead of `host` when relevant in + configuration + +--- + configure | Bin 682949 -> 682314 bytes + configure.ac | 10 +++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/configure b/configure +index f81f4ca213b710395b61b64d1380318d4d80867d..b393e6e2871a942e0171f1a52b70f75ef74f780a 100755 +GIT binary patch +delta 382 +zcmX?lUGvl>&4w+Esyn8O?`5>&ElDg&Pc4a0%*jkF)}0=(m(dngX#2w*j4@28V$(0M +zFi)HQa5v-Y=?MmGT+?stVdP~=$?_$tCeVF19K@F4I5U +zVH4S|wwG}+i@bsYNDL;+rJ#_SQ=AHlQVFkN& +zd+d3(9Zb`AtYPEdu5^hlt_dpK9K!A)Jbhvrvm8H)pK?;B8!l!t#SnCS!Z>65{|xr~ +zjHsTQ{82+<`h?qz72E5w*?AbJD}82^n9fto&NY2~4m&5t;^V@#oqI3i7MAJ%DwqU?d|Z?iY!xc3 +z6-qKv^SBg%VETPAHnr*ftC>otpS{Z3$pg{^)82mXAR`bn0WmWWvj8#c_In4}?0BaC +zv|{Jou6>Se9n1^xsX_NBR0pbmyQbR|u*QYK + +diff --git a/configure.ac b/configure.ac +index 0862b381ff..26de5bed24 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -597,7 +597,7 @@ AS_IF([test x"$enable_ocamldoc" = "xno"], + # Initialization of libtool + # Allow the MSVC linker to be found even if ld isn't installed. + # User-specified LD still takes precedence. +-AC_CHECK_TOOLS([LD],[ld link]) ++AC_CHECK_TARGET_TOOLS([LD],[ld link]) + # libtool expects host_os=mingw for native Windows + # Also, it has been observed that, on some platforms (e.g. msvc) LT_INIT + # alters the CFLAGS variable, so we save its value before calling the macro +@@ -1027,7 +1027,7 @@ AS_CASE([$flexdll_source_dir,$supports_shared_libraries,$flexlink,$host], + + mkexe_cmd_exp="$CC" + +-AS_CASE([$ocaml_cc_vendor,$host], ++AS_CASE([$ocaml_cc_vendor,$target], + [*,x86_64-*-darwin*], + [oc_ldflags='-Wl,-no_compact_unwind'; + AC_DEFINE([HAS_ARCH_CODE32], [1])], +@@ -1045,7 +1045,7 @@ AS_CASE([$ocaml_cc_vendor,$host], + ) + ostype="Cygwin"], + [*,*-*-mingw32*], +- [AS_CASE([$host], ++ [AS_CASE([$target], + [i686-*-*], [oc_dll_ldflags="-static-libgcc"]) + ostype="Win32" + toolchain="mingw" +@@ -1342,7 +1342,7 @@ system=unknown + # preserving $arch = 'none' <=> $system = 'unknown' + has_native_backend=no + native_ldflags="" +-AS_CASE([$host], ++AS_CASE([$target], + [[i[3456]86-*-linux*]], + [arch=i386; system=linux], + [[i[3456]86-*-freebsd*]], +@@ -1479,7 +1479,7 @@ AS_IF([$natdynlink], + + AC_DEFINE_UNQUOTED([OCAML_OS_TYPE], ["$ostype"]) + +-AC_CHECK_TOOL([DIRECT_LD],[ld]) ++AC_CHECK_TARGET_TOOL([DIRECT_LD],[ld]) + AS_IF([test -z "$PARTIALLD"], + [AS_CASE(["$host,$ocaml_cc_vendor"], + [x86_64-*-darwin*,gcc-*], [PACKLD_FLAGS=' -arch x86_64'], +-- +2.45.2 + diff --git a/patches/5.2.1/0005-Use-the-strip-command-detected-by-libtool.patch b/patches/5.2.1/0005-Use-the-strip-command-detected-by-libtool.patch new file mode 100644 index 00000000..a0e2cc9f --- /dev/null +++ b/patches/5.2.1/0005-Use-the-strip-command-detected-by-libtool.patch @@ -0,0 +1,42 @@ +From a67f2491770af3937b9cf5c548855dff678d99b5 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Fri, 5 Jul 2024 12:42:36 +0200 +Subject: [PATCH 05/14] Use the `strip` command detected by libtool + +Instead of using `strip` unconditionally to build `tmpheader.exe`, use +the `strip` command detected by `libtool` during configure so that it is +replaced with `:` when the command is absent and it becomes easy to +override it if need be +--- + Makefile.config.in | 1 + + stdlib/Makefile | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Makefile.config.in b/Makefile.config.in +index 4243bebad9..b91634efb6 100644 +--- a/Makefile.config.in ++++ b/Makefile.config.in +@@ -185,6 +185,7 @@ OCAMLOPT_CFLAGS=@ocamlc_cflags@ + OCAMLOPT_CPPFLAGS=@ocamlc_cppflags@ + NATIVECCLIBS=@cclibs@ + SYSTHREAD_SUPPORT=@systhread_support@ ++STRIP=@STRIP@ + PACKLD=@PACKLD@$(EMPTY) + CCOMPTYPE=@ccomptype@ + TOOLCHAIN=@toolchain@ +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 50f825a1b3..b6286920f2 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -98,7 +98,7 @@ tmpheader.exe: $(HEADERPROGRAM).$(O) + $(V_MKEXE)$(call MKEXE_VIA_CC,$@,$^) + # FIXME This is wrong - mingw could invoke strip; MSVC equivalent? + ifneq "$(UNIX_OR_WIN32)" "win32" +- strip $@ ++ $(STRIP) $@ + endif + + stdlib.cma: $(OBJS) +-- +2.45.2 + diff --git a/patches/5.2.1/0006-Strip-tmpheader.exe-also-on-Windows.patch b/patches/5.2.1/0006-Strip-tmpheader.exe-also-on-Windows.patch new file mode 100644 index 00000000..5b6d5950 --- /dev/null +++ b/patches/5.2.1/0006-Strip-tmpheader.exe-also-on-Windows.patch @@ -0,0 +1,32 @@ +From aefbbb813cdc27252153d2cf043900681c8689d8 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Fri, 5 Jul 2024 12:58:58 +0200 +Subject: [PATCH 06/14] Strip tmpheader.exe also on Windows + +GNU strip can be called safely on binaries generated by cl as well as by +MinGW GCC (even if it doesn't produce a smaller executable for +cl-generated binaries) so invoke strip also on Windows so that MinGW +binaries are properly stripped +Tested with GNU strip 2.42 +--- + stdlib/Makefile | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index b6286920f2..a7f2e60a7a 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -96,10 +96,7 @@ endif + .INTERMEDIATE: tmpheader.exe + tmpheader.exe: $(HEADERPROGRAM).$(O) + $(V_MKEXE)$(call MKEXE_VIA_CC,$@,$^) +-# FIXME This is wrong - mingw could invoke strip; MSVC equivalent? +-ifneq "$(UNIX_OR_WIN32)" "win32" + $(STRIP) $@ +-endif + + stdlib.cma: $(OBJS) + $(V_LINKC)$(CAMLC) -a -o $@ $^ +-- +2.45.2 + diff --git a/patches/5.2.1/0007-Allow-ocaml-as-a-target-OS-to-configure-freestanding.patch b/patches/5.2.1/0007-Allow-ocaml-as-a-target-OS-to-configure-freestanding.patch new file mode 100644 index 00000000..0af801e5 --- /dev/null +++ b/patches/5.2.1/0007-Allow-ocaml-as-a-target-OS-to-configure-freestanding.patch @@ -0,0 +1,65 @@ +From 627cf134087f67001306b9480a51f6c5ea082758 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Mon, 26 Feb 2024 11:51:11 +0100 +Subject: [PATCH 07/14] Allow `ocaml` as a target OS to configure freestanding + cross-compilers + +Allow the use of *-*-ocaml or *-*-*-ocaml target triplets to stand for +freestanding cross-compilers by temporarily rewriting the target OS to +`none` when generating the canonical target + +This allows to use *-*-ocaml and *-*-*-ocaml prefixes for cross-compiler +specific toolchains, so that all the specific tools (for instance +aarch64-solo5-ocaml-gcc, etc.) are automatically discovered +--- + configure | Bin 682314 -> 682823 bytes + configure.ac | 17 +++++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/configure b/configure +index b393e6e2871a942e0171f1a52b70f75ef74f780a..498bc2042686e7fc202a6ecdfaa1ca6d2c780efc 100755 +GIT binary patch +delta 551 +zcmb7Au}T9$5G64hyAYqSwV3K0acut*y?#&dEm?A?al#Tc8Uibbka`3PGf +zpCDMKu(PuF8=Rb?7e!E(x6Hg5-n^N|dGPQQ4DU;Kqd^T0mC`*BI>uB9Kno5{LJrPa +z(9s4uhR8b1E@YNKtkbSkWZ=9Hj?%6+Xr$_cp`MYBJG>gWODae>4IMa;o{|61aQCv0LGEUD~e8z +zTTP$8oLnUJu%5@31`e*51@l62Dx261{k<^X;#0yeh(n|C<>7x0jx1mLPY!+`Kb@Rb +sH>dMqd4KjYD&17JzPbN#R&m=Nml$Qn3ZueUWvnr(jP+T2yz%<{2ER13{Qv*} + +delta 60 +zcmX?pP4mg9ZU +F7XS(}7}x*+ + +diff --git a/configure.ac b/configure.ac +index 26de5bed24..6f02258356 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -286,7 +286,24 @@ AC_CONFIG_COMMANDS_PRE(OCAML_QUOTED_STRING_ID) + + AC_CANONICAL_BUILD + AC_CANONICAL_HOST ++# Allow "ocaml" as target OS for freestanding compiler by temporarily rewriting ++# the target OS to "none" to generate the canonical target ++real_target_alias="$target_alias" ++AS_CASE([$target_alias], ++ [*-*-*-ocaml], ++ [ac_save_IFS=$IFS ++ IFS='-' ++ set x $target_alias ++ target_alias="$2-$3-none" ++ IFS=$ac_save_IFS], ++ [*-*-ocaml], ++ [ac_save_IFS=$IFS ++ IFS='-' ++ set x $target_alias ++ target_alias="$2-none" ++ IFS=$ac_save_IFS]) + AC_CANONICAL_TARGET ++target_alias="$real_target_alias" + + # Override cross_compiling and ac_tool_prefix variables since the C toolchain is + # used to generate target code when building a cross compiler +-- +2.45.2 + diff --git a/patches/5.2.1/0008-Define-OS-type-to-None.patch b/patches/5.2.1/0008-Define-OS-type-to-None.patch new file mode 100644 index 00000000..089f6897 --- /dev/null +++ b/patches/5.2.1/0008-Define-OS-type-to-None.patch @@ -0,0 +1,38 @@ +From 8056ab2f13faa7a484dc1d985208a6066cebfc89 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Mon, 26 Feb 2024 12:06:45 +0100 +Subject: [PATCH 08/14] Define OS type to None + +--- + configure | Bin 682823 -> 682873 bytes + configure.ac | 4 +++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index 498bc2042686e7fc202a6ecdfaa1ca6d2c780efc..0eebc7063ceea9c5c392b02e68dce28144556545 100755 +GIT binary patch +delta 89 +zcmX?pP4nk9&4w1n7N!>F7M2#)Eo{-()pfLVwRH3H^HOWHz|7Q~G))C7E(IXSFD|Jp +lNVQe+1IkWsRN)k!zQC8At3CHR8xXStF~|1Y>zubH0{~+sAF2QV + +delta 44 +ycmex)P4oCQ&4w1n7N!>F7M2#)Eo{-(r@y(&F3>*rIvWtP12M<;xz{=GOa=hQ!xZiS + +diff --git a/configure.ac b/configure.ac +index 6f02258356..5523a1013c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1090,7 +1090,9 @@ AS_CASE([$ocaml_cc_vendor,$target], + [oc_ldflags='-brtl -bexpfull' + AC_DEFINE([HAS_ARCH_CODE32], [1])], + [gcc-*,powerpc-*-linux*], +- [oc_ldflags="-mbss-plt"]) ++ [oc_ldflags="-mbss-plt"], ++ [*,*-*-none|*,*-*-elf], ++ [ostype="None"]) + + ## Program to use to install files + AC_PROG_INSTALL +-- +2.45.2 + diff --git a/patches/5.2.1/0009-Add-freestanding-targets-to-supported-configurations.patch b/patches/5.2.1/0009-Add-freestanding-targets-to-supported-configurations.patch new file mode 100644 index 00000000..8c24fcb1 --- /dev/null +++ b/patches/5.2.1/0009-Add-freestanding-targets-to-supported-configurations.patch @@ -0,0 +1,40 @@ +From cbcf96dca5420b9a2665b0064c5ba2b37b7ecaa6 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Mon, 26 Feb 2024 19:35:26 +0100 +Subject: [PATCH 09/14] Add freestanding targets to supported configurations + +--- + configure | Bin 682873 -> 683028 bytes + configure.ac | 6 +++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index 0eebc7063ceea9c5c392b02e68dce28144556545..d95fd568597e59d6f9e92aacadc9f50840dcee16 100755 +GIT binary patch +delta 99 +zcmex)O>@c(&4w1n7N!>F7M2#)7Pc+yfyvYRBiK2opN(bbWXa3VOPzi;f!$ad#8R-f +sR#4X9Qcy@tEK1HWGtt%31uNK_$ZiZ)+8&t94#XTl%(*=F7M2#)7Pc+yfyvW13UCOw|4(KIVh$kY-2OkAOOyiuw<;1a + +diff --git a/configure.ac b/configure.ac +index 5523a1013c..3b2de0b053 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1458,7 +1458,11 @@ AS_CASE([$target], + [x86_64-*-cygwin*], + [has_native_backend=yes; arch=amd64; system=cygwin], + [riscv64-*-linux*], +- [has_native_backend=yes; arch=riscv; model=riscv64; system=linux] ++ [has_native_backend=yes; arch=riscv; model=riscv64; system=linux], ++ [x86_64-*-none], ++ [has_native_backend=yes; arch=amd64; system=none], ++ [aarch64-*-none], ++ [has_native_backend=yes; arch=arm64; system=none] + ) + + AS_CASE([$arch], +-- +2.45.2 + diff --git a/patches/5.2.1/0010-Check-that-the-configured-and-the-installed-OCaml-ar.patch b/patches/5.2.1/0010-Check-that-the-configured-and-the-installed-OCaml-ar.patch new file mode 100644 index 00000000..87b0c450 --- /dev/null +++ b/patches/5.2.1/0010-Check-that-the-configured-and-the-installed-OCaml-ar.patch @@ -0,0 +1,46 @@ +From 156caacd6b9b4d3d83adf02ffd0c68f11a0ff5a7 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Tue, 19 Mar 2024 19:14:29 +0100 +Subject: [PATCH 10/14] Check that the configured and the installed OCaml are + compatible + +--- + configure | Bin 683028 -> 683595 bytes + configure.ac | 7 +++++++ + 2 files changed, 7 insertions(+) + +diff --git a/configure b/configure +index d95fd568597e59d6f9e92aacadc9f50840dcee16..58c25a0c685bf6860c63c9c394d191f9281bd1b3 100755 +GIT binary patch +delta 436 +zcmbPoL-X_<&4w1n7N!>F7M2#)Eo{FyO_deGQx%F*3rjPLQWX*v^78X^lZ*0;i*=Lp +za|<$aQi~Mw(-cZFQWc65b5j+{Qj3Z+^Yf-}+{1384HAV4z!YWX6_+ID9)8%)`*8P*$vF7M2#)Eo{Fyr$_j)>$S)8umLeU5OV-A=k|CWt~ZGQuvrin + +diff --git a/configure.ac b/configure.ac +index 3b2de0b053..c5b2a3f217 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -825,6 +825,13 @@ AS_IF( + CPPFLAGS_FOR_BUILD='$(CPPFLAGS)' + LDFLAGS_FOR_BUILD='$(LDFLAGS)'], + [cross_compiler=true ++ # We require a non-cross-compiler of the same version ++ AC_MSG_CHECKING([the version of the installed OCaml compiler]) ++ already_installed_version=`ocamlc -vnum` ++ AS_IF([test x"AC_PACKAGE_VERSION" = x"$already_installed_version"], ++ [AC_MSG_RESULT([compatible (AC_PACKAGE_VERSION)])], ++ [AC_MSG_ERROR(m4_normalize([incompatible (AC_PACKAGE_VERSION vs ++ $already_installed_version)]))]) + AC_MSG_NOTICE([detecting the C toolchain for build]) + AX_PROG_CC_FOR_BUILD]) + +-- +2.45.2 + diff --git a/patches/5.2.1/0011-Use-the-target-pkg-config-to-detect-zstd.patch b/patches/5.2.1/0011-Use-the-target-pkg-config-to-detect-zstd.patch new file mode 100644 index 00000000..f4d0a0e5 --- /dev/null +++ b/patches/5.2.1/0011-Use-the-target-pkg-config-to-detect-zstd.patch @@ -0,0 +1,44 @@ +From 40f00c44630bae376edf63dc5f76150b3a8065af Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Wed, 20 Mar 2024 17:41:26 +0100 +Subject: [PATCH 11/14] Use the target pkg-config to detect zstd + +Make sure that we don't detect zstd on build when we are building a +cross-compiler, as the native zstd has no reason to be compatible with +the cross toolchain +--- + configure | Bin 683595 -> 683354 bytes + configure.ac | 2 +- + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure b/configure +index 58c25a0c685bf6860c63c9c394d191f9281bd1b3..e364c57560a234055311de9b09ff0f399fd0f44a 100755 +GIT binary patch +delta 151 +zcmV;I0BHZq+$q}HDS(6lgaU*Egam{Iga(8MvRQ2tN&UVRC0>bYEd? +zX<>6Mx88CHV+59$0ST8ba0d&QSa%2*m(sogDwlJ22ppG`a0ef^tak{b1DEr^2oaZv +zcnA~)A|NIvAeVu72pb4JB4%N1b7dm8OnV4E0hi=`2q6SzY;$FouzUy_hXsBJw*`I) +FM({SFH0=NY + +delta 171 +zcmcb0OY`&{&4w1n7N!>F7M2#)7Pc1lEgUvQ)4#lA3T7_IPM_Ylo5Ongft!qiVBUq@ +z9J8lOlyUHFk1yuf&OAL}1(W!6t#S^D>6zsm^3z4WFv@OUUe2+YdHSzX4({zst2qo9 +zr~BKp@ktbv#0Pl0$2g?s_5lEp)jm4_ + +diff --git a/configure.ac b/configure.ac +index c5b2a3f217..14d0356368 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2261,7 +2261,7 @@ AC_CHECK_HEADER([spawn.h], + [AC_CHECK_FUNC([posix_spawn], + [AC_CHECK_FUNC([posix_spawnp], [AC_DEFINE([HAS_POSIX_SPAWN])])])]) + +-AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [false]) ++AC_PATH_TARGET_TOOL([PKG_CONFIG], [pkg-config], [false]) + + ## ZSTD compression library + +-- +2.45.2 + diff --git a/patches/5.2.1/0012-WIP-Add-a-Makefile.cross-for-recipes-to-build-a-cros.patch b/patches/5.2.1/0012-WIP-Add-a-Makefile.cross-for-recipes-to-build-a-cros.patch new file mode 100644 index 00000000..44c04581 --- /dev/null +++ b/patches/5.2.1/0012-WIP-Add-a-Makefile.cross-for-recipes-to-build-a-cros.patch @@ -0,0 +1,122 @@ +From 4ab2e100f97da1a4251137dfaf473af705f0274f Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Fri, 23 Feb 2024 16:56:07 +0100 +Subject: [PATCH 12/14] WIP Add a Makefile.cross for recipes to build a + cross-compiler + +Define cross.opt and cross-install targets + +FIXME: Problems of inconsistencies between compilation options (only +about zstd?) between the native toolchain and the cross toolchain may +break the build? +--- + Makefile | 2 ++ + Makefile.cross | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 85 insertions(+) + create mode 100644 Makefile.cross + +diff --git a/Makefile b/Makefile +index df191af79c..cb6b3f4484 100644 +--- a/Makefile ++++ b/Makefile +@@ -2732,6 +2732,8 @@ endif + + include .depend + ++include Makefile.cross ++ + Makefile.config Makefile.build_config: config.status + config.status: + @echo "Please refer to the installation instructions:" +diff --git a/Makefile.cross b/Makefile.cross +new file mode 100644 +index 0000000000..b993783d2f +--- /dev/null ++++ b/Makefile.cross +@@ -0,0 +1,83 @@ ++#************************************************************************** ++#* * ++#* OCaml * ++#* * ++#* Samuel Hym, Tarides * ++#* * ++#* Copyright 2024 Tarides * ++#* * ++#* All rights reserved. This file is distributed under the terms of * ++#* the GNU Lesser General Public License version 2.1, with the * ++#* special exception on linking described in the file LICENSE. * ++#* * ++#************************************************************************** ++ ++# Recipes to build a cross-compiler (_not_ cross-compiling the compiler), aka ++# generating code that will run on `target`, assuming that a non-cross OCaml ++# compiler (so targetting our build machine) of the same version is available in ++# $PATH ++ ++# We assume no zstd for the cross-compiler (ie no requirement on zstd for the ++# target) ++# Still the cross-compiler will run on host, not target. And as a consequence of ++# the rules linking it, the cross-compilers will be linked with the _build_ ++# version of libcomprmarsh, so we still must discover the flags to link with ++# libzstd if it was set up in the non-cross compiler, so we rely on the ++# pkg-config command to get the linking flags for zstd ++PKG_CONFIG := pkg-config ++# This is used only once, so it doesn't have to be much lazier ++NATIVE_ZSTD_LIBS=ZSTD_LIBS="$(shell $(PKG_CONFIG) --libs libzstd)" ++# As the libcomprmarsh built by the C cross compiler will not be linked in, we ++# can build an empty one ++NO_ZSTD=libcomprmarsh_OBJECTS= ++ ++CROSS_OVERRIDES=OCAMLRUN=ocamlrun NEW_OCAMLRUN=ocamlrun \ ++ BOOT_OCAMLLEX=ocamllex OCAMLYACC=ocamlyacc ++CROSS_COMPILER_OVERRIDES=$(CROSS_OVERRIDES) CAMLC=ocamlc CAMLOPT=ocamlopt \ ++ BEST_OCAMLC=ocamlc BEST_OCAMLOPT=ocamlopt BEST_OCAMLLEX=ocamllex ++ ++INSTALL_OVERRIDES=build_ocamldoc=false WITH_DEBUGGER= ++ ++# Freestanding target custom options ++ifeq "$(SYSTEM)" "none" ++RUNTIME_BUILD_OVERRIDES=runtime_PROGRAMS= ++INSTALL_OVERRIDES += runtime_PROGRAMS=`which ocamlrun` \ ++ runtime_BYTECODE_STATIC_LIBRARIES=runtime/ld.conf ++else ++RUNTIME_BUILD_OVERRIDES= ++endif ++ ++cross.opt: ++ $(MAKE) runtime-all $(NO_ZSTD) $(RUNTIME_BUILD_OVERRIDES) ++ $(MAKE) ocamlc ocamlopt $(TOOLS_BYTECODE_TARGETS) expunge \ ++ $(CROSS_COMPILER_OVERRIDES) ++ $(MAKE) library $(CROSS_OVERRIDES) ++ifneq "$(SYSTEM)" "none" ++ $(MAKE) ocamlyacc $(CROSS_OVERRIDES) ++ $(MAKE) ocamllex $(CROSS_COMPILER_OVERRIDES) ++endif ++ $(MAKE) ocaml $(CROSS_COMPILER_OVERRIDES) ++ $(MAKE) -C otherlibs all $(CROSS_OVERRIDES) ++ # Opt ++ $(MAKE) runtimeopt $(NO_ZSTD) ++ $(MAKE) ocamlc.opt ocamlopt.opt $(TOOLS_NATIVE_TARGETS) \ ++ $(NO_ZSTD) $(CROSS_COMPILER_OVERRIDES) $(NATIVE_ZSTD_LIBS) ++ $(MAKE) libraryopt $(NO_ZSTD) $(CROSS_OVERRIDES) ++ $(MAKE) otherlibrariesopt ocamltoolsopt $(NO_ZSTD) $(CROSS_OVERRIDES) ++ $(MAKE) tools-allopt.opt $(NO_ZSTD) $(CROSS_COMPILER_OVERRIDES) ++ ++.PHONY: cross-install ++cross-install: ++ # dummy files ++ touch \ ++ $(addprefix toplevel/, \ ++ $(foreach ext,cmi cmt cmti cmx, native/nat__dummy__.$(ext)) \ ++ all__dummy__.cmx topstart.o native/tophooks.cmi) ++ $(LN) `which ocamlyacc` yacc/ocamlyacc.opt$(EXE) ++ $(LN) `which ocamllex` lex/ocamllex.opt$(EXE) ++ifeq "$(SYSTEM)" "none" ++ $(LN) `which ocamlyacc` yacc/ocamlyacc$(EXE) ++ $(LN) `which ocamllex` lex/ocamllex$(EXE) ++endif ++ # Real installation ++ $(MAKE) install $(INSTALL_OVERRIDES) OCAMLRUN=ocamlrun +-- +2.45.2 + diff --git a/patches/5.2.1/0013-Set-Max_domains-to-1.patch b/patches/5.2.1/0013-Set-Max_domains-to-1.patch new file mode 100644 index 00000000..2eb55151 --- /dev/null +++ b/patches/5.2.1/0013-Set-Max_domains-to-1.patch @@ -0,0 +1,35 @@ +From bde7866513c8deeddd9165d05502162229abd13a Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Fri, 12 Apr 2024 19:21:52 +0200 +Subject: [PATCH 13/14] Set Max_domains to 1 + +Solo5 is single-core with no scheduler, so avoid the useless memory +waste + +Note that since PR#13272 the maximum number of domains can set using a +parameter in OCAMLRUNPARAM so `getenv` might be a better place to set +this limit in the future +--- + runtime/caml/domain.h | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/runtime/caml/domain.h b/runtime/caml/domain.h +index 4b9be80b41..986486478c 100644 +--- a/runtime/caml/domain.h ++++ b/runtime/caml/domain.h +@@ -31,11 +31,7 @@ extern "C" { + + /* The runtime currently has a hard limit on the number of domains. + This hard limit may go away in the future. */ +-#ifdef ARCH_SIXTYFOUR +-#define Max_domains 128 +-#else +-#define Max_domains 16 +-#endif ++#define Max_domains 1 + + /* is the minor heap full or an external interrupt has been triggered */ + Caml_inline int caml_check_gc_interrupt(caml_domain_state * dom_st) +-- +2.45.2 + diff --git a/patches/5.2.1/0014-Set-stack-as-non-executable-on-freestanding-targets.patch b/patches/5.2.1/0014-Set-stack-as-non-executable-on-freestanding-targets.patch new file mode 100644 index 00000000..d0e29b0f --- /dev/null +++ b/patches/5.2.1/0014-Set-stack-as-non-executable-on-freestanding-targets.patch @@ -0,0 +1,53 @@ +From d6d0345ba0d079ffc17c397ae1773e50ecc470b1 Mon Sep 17 00:00:00 2001 +From: Samuel Hym +Date: Mon, 29 Apr 2024 18:21:24 +0200 +Subject: [PATCH 14/14] Set stack as non-executable on freestanding targets + +--- + asmcomp/amd64/emit.mlp | 2 +- + asmcomp/arm64/emit.mlp | 2 +- + runtime/amd64.S | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp +index 619ce9c3c5..19f896c1ac 100644 +--- a/asmcomp/amd64/emit.mlp ++++ b/asmcomp/amd64/emit.mlp +@@ -1079,7 +1079,7 @@ let end_assembly() = + D.size frametable (ConstSub (ConstThis, ConstLabel frametable)) + end; + +- if system = S_linux then ++ if system = S_linux || system = S_unknown then + (* Mark stack as non-executable, PR#4564 *) + D.section [".note.GNU-stack"] (Some "") [ "%progbits" ]; + +diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp +index 1816f8c345..41769e4f93 100644 +--- a/asmcomp/arm64/emit.mlp ++++ b/asmcomp/arm64/emit.mlp +@@ -1217,7 +1217,7 @@ let end_assembly () = + emit_symbol_type emit_symbol lbl "object"; + emit_symbol_size lbl; + begin match Config.system with +- | "linux" -> ++ | "linux" | "none" -> + (* Mark stack as non-executable *) + ` .section .note.GNU-stack,\"\",%progbits\n` + | _ -> () +diff --git a/runtime/amd64.S b/runtime/amd64.S +index 49c712b167..be0856a72b 100644 +--- a/runtime/amd64.S ++++ b/runtime/amd64.S +@@ -1386,7 +1386,7 @@ G(caml_negf_mask): + G(caml_absf_mask): + .quad 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF + +-#if defined(SYS_linux) ++#if defined(SYS_linux) || defined(SYS_none) + /* Mark stack as non-executable, PR#4564 */ + .section .note.GNU-stack,"",%progbits + #endif +-- +2.45.2 + From d4bd77f4338b6fe4c40ac861d259d43bbbc06f76 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 5 Apr 2024 18:43:33 +0200 Subject: [PATCH 78/92] Update the compiler version in CI to 5.2.1 --- .cirrus.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 02e0837b..a57d8d40 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,7 +6,7 @@ freebsd_task: OPAMYES: 1 env: matrix: - - OCAML_VERSION: 5.0.0 + - OCAML_VERSION: 5.2.1 pkg_install_script: pkg install -y ocaml-opam gmp gmake pkgconf bash opam_ocaml_cache: folder: $HOME/.opam diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec62310d..ac20731c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ jobs: test: strategy: matrix: - ocaml-compiler: [5.0.0] + ocaml-compiler: [5.2.1] name: OCaml ${{ matrix.ocaml-compiler }} runs-on: ubuntu-latest steps: From 9d3546e69530d9a19316f2bdd2df980c882584e1 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 9 Apr 2024 16:01:45 +0200 Subject: [PATCH 79/92] Use an order-only dependency for nolibc test directory Co-authored-by: Fabrice Buoro --- nolibc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nolibc/Makefile b/nolibc/Makefile index 99a3a860..d5dfa46a 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -54,4 +54,4 @@ test-include/: test-include/sys/: test-include/ mkdir -p $@ -test-headers: test-include/sys/ $(TEST_H_OBJS) +test-headers: $(TEST_H_OBJS) | test-include/sys/ From f556216f5da8890ba0dce56fee20efe135a8706b Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 9 Apr 2024 16:17:09 +0200 Subject: [PATCH 80/92] Update comments in nolibc' `signal.h` Rephrase the comments to catch up with the evolutions of `signal.h` Co-authored-by: Fabrice Buoro --- nolibc/include/signal.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/nolibc/include/signal.h b/nolibc/include/signal.h index 43a00ff3..c798f62c 100644 --- a/nolibc/include/signal.h +++ b/nolibc/include/signal.h @@ -1,6 +1,13 @@ #ifndef _SIGNAL_H #define _SIGNAL_H +/* + * The following definitions are required not only to build the OCaml runtime + * but also the freestanding version of GMP used by Mirage. + * Note though that Solo5 does not implement signals, so we should not trigger a + * situation where these values are really used. + */ + typedef int jmp_buf; int setjmp(jmp_buf); void (*signal(int sig, void (*func)(int)))(int); @@ -9,15 +16,7 @@ void (*signal(int sig, void (*func)(int)))(int); #define SIG_ERR 0 #define SIG_BLOCK 0 #define SIG_SETMASK 0 -/* - * The following definitions are not required by the OCaml runtime, but are - * needed to build the freestanding version of GMP used by Mirage. - * For OCaml 5.0.0, it's not totally true. SIG_{BLOCK,SETMASK,IGN,DFL) are - * needed by the OCaml runtime. - * - * NOTE: Solo5 does not implement signals, but we should not trigger - * a situation where these values are really used. - */ + #define SIGFPE 1 int raise(int); From 3386f83644b9cebfa01573f6c574720a3fc605f3 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Fri, 12 Apr 2024 19:42:30 +0200 Subject: [PATCH 81/92] Ignore `sigfillset` Follow a suggestion by Christiano Haesbaert, as Solo5 doesn't provide signals, it might just be ignored As of OCaml 5.2.0 beta1, `sigfillset` is only used in functions creating threads, and so that will abort in any case. Ignoring the function may make it more future-proof, though. --- nolibc/stubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nolibc/stubs.c b/nolibc/stubs.c index c8c0b2ec..b75d40b7 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -141,7 +141,7 @@ STUB_IGNORE(int, pthread_cond_broadcast, 0); STUB_ABORT(pthread_self); STUB_ABORT(pthread_detach); -STUB_ABORT(sigfillset); +STUB_IGNORE(int, sigfillset, 0); STUB_ABORT(sigwait); STUB_ABORT(usleep); STUB_ABORT(strerror_r); From a8e1f383f918a6b84921f0af96e576db7f782916 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 16 Apr 2024 14:00:03 +0200 Subject: [PATCH 82/92] Change pthread_create stub to report a failure to create Make extra sure that, if `pthread_create` is called, the caller will know it failed --- nolibc/include/errno.h | 1 + nolibc/stubs.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index fd3a6660..72591d77 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -3,6 +3,7 @@ extern int errno; #define EBADF 9 /* Bad file number */ +#define EAGAIN 11 /* Resource temporarily unavailable */ #define ENOENT 2 /* No such file or directory */ #define ENOMEM 12 /* Out of memory */ #define EBUSY 16 /* Device or resource busy */ diff --git a/nolibc/stubs.c b/nolibc/stubs.c index b75d40b7..8e73125d 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -108,7 +108,7 @@ STUB_ABORT(mkdir); /* pthread.h */ STUB_IGNORE(int, pthread_join, 0); -STUB_IGNORE(int, pthread_create, 0); +STUB_IGNORE(int, pthread_create, EAGAIN); STUB_IGNORE(int, pthread_attr_init, 0); STUB_ABORT(pthread_cleanup_push); STUB_ABORT(pthread_cleanup_pop); From c799c92865c3ccd1ba53744259424bff86052f7d Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 16 Apr 2024 14:11:42 +0200 Subject: [PATCH 83/92] Ensure that library dependencies work across Makefiles Since the main Makefile doesn't know the dependencies for the nolibc and openlibm libraries, create intermediate phony targets. That scheme ensures, even when one library already exists, that: - when building a target that depend on that library, a recursive make is invoked to check that it is up-to-date, - if the recursive make doesn't update the library, the dependency on the library is not a reason to rebuild the target. --- Makefile | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7d5e84c8..67ab833d 100644 --- a/Makefile +++ b/Makefile @@ -18,14 +18,24 @@ LIBS := openlibm/libopenlibm.a nolibc/libnolibc.a LIB_CFLAGS=-I$(TOP)/nolibc/include -include _solo5/overrides.h # NOLIBC +# Use a phony target indirection, so that nolibc/Makefile is always checked to +# see whether the library should be rebuilt while avoiding useless rebuild if +# nolibc/libnolibc.a was up-to-date NOLIBC_CFLAGS=$(LIB_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include -nolibc/libnolibc.a: +nolibc/libnolibc.a: phony-nolibc + +.PHONY: phony-nolibc +phony-nolibc: $(MAKE) -C nolibc libnolibc.a \ "CC=$(MAKECONF_TOOLCHAIN)-cc" \ "FREESTANDING_CFLAGS=$(NOLIBC_CFLAGS)" # OPENLIBM -openlibm/libopenlibm.a: +# See NOLIBC for explanations of the phony target +openlibm/libopenlibm.a: phony-openlibm + +.PHONY: phony-openlibm +phony-openlibm: $(MAKE) -C openlibm libopenlibm.a \ "CC=$(MAKECONF_TOOLCHAIN)-cc" \ "CPPFLAGS=$(LIB_CFLAGS)" From 7e11c3fe49edbaeb9b509e65f58646332dd97e5d Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 6 May 2024 17:32:54 +0200 Subject: [PATCH 84/92] Handle `mmap(addr..., MAP_FIXED, ...)` uses OCaml calls mmap with a non-null address and with the `MAP_FIXED` flag only on already reserved memory to commit or decommit that memory block, ie to set its protection to `PROT_READ|PROT_WRITE` or to `PROT_NONE`, in the `caml_mem_commit` and `caml_mem_decommit` functions So we accept this particular case without allocating memory that would leak since the OCaml code base simply ignores the returned value (as `MAP_FIXED` enforces the returned value to be either `addr` or `MAP_FAILED`) Accordingly, remove the man page extract that says that `addr` is just a hint since OCaml always sets `MAP_FIXED` when `addr` isn't null --- nolibc/mmap.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/nolibc/mmap.c b/nolibc/mmap.c index 209bfde3..46e1af13 100644 --- a/nolibc/mmap.c +++ b/nolibc/mmap.c @@ -7,14 +7,19 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { /* man page for mmap says: - * If addr is NULL, then the kernel chooses the (page-aligned) address at - * which to create the mapping; this is the most portable method of creat‐ - * ing a new mapping. If addr is not NULL, then the kernel takes it as a hint - * about where to place the mapping; [...] If another apping already exists - * there, the kernel picks a new address that may or *may not* depend on the hint. + * If addr is NULL, then the kernel chooses the (page-aligned) address at + * which to create the mapping; this is the most portable method of creating a + * new mapping. * * For our purpose (Solo5 & OCaml), OCaml might use a NULL addr and force us to - * use posix_memalign. If addr is not NULL we can use [malloc()] instead of. + * use posix_memalign. + * OCaml calls mmap with a non-null address and with the MAP_FIXED flag only + * on already reserved memory to commit or decommit that memory block, ie to + * set its protection to PROT_READ|PROT_WRITE or to PROT_NONE, in the + * caml_mem_commit and caml_mem_decommit functions. + * So we accept this particular case without allocating memory that would leak + * since the OCaml code base simply ignores the returned value (as MAP_FIXED + * enforces the returned value to be either addr or MAP_FAILED). * * The OCaml usage of [mmap()] is only to allocate some spaces, only [fildes * == -1] is handled so. @@ -31,16 +36,20 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { } void *ptr = NULL; - /* XXX(palainp): Does it worth to have a test on addr here? */ + if (addr == NULL) { /* Solo5 may returns -1 and set errno on error, just return MAP_FAILED. It doesn't modify ptr on error: ptr will still be NULL */ posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); } else { - ptr = malloc(len); - if (ptr == NULL) { - errno = ENOMEM; + if ((flags & MAP_FIXED) != 0) { + /* Case where mmap is called to commit or decommit already reserved + * memory. Since we ignore prot, we can simply let it go through */ + return addr; + } else { + /* We cannot handle this case */ + errno = EINVAL; } } From 19735eb359e80d533c6b62cb45b7edb73821d35a Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 6 May 2024 19:36:24 +0200 Subject: [PATCH 85/92] Reformulate two comments in `mmap` --- nolibc/mmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nolibc/mmap.c b/nolibc/mmap.c index 46e1af13..3f99fc07 100644 --- a/nolibc/mmap.c +++ b/nolibc/mmap.c @@ -21,8 +21,8 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { * since the OCaml code base simply ignores the returned value (as MAP_FIXED * enforces the returned value to be either addr or MAP_FAILED). * - * The OCaml usage of [mmap()] is only to allocate some spaces, only [fildes - * == -1] is handled so. + * The OCaml runtime uses [mmap()] only to allocate memory, so only + * [fildes == 1] is handled. */ (void)prot; // unused argument @@ -38,9 +38,9 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { void *ptr = NULL; if (addr == NULL) { - /* Solo5 may returns -1 and set errno on error, just return MAP_FAILED. - It doesn't modify ptr on error: ptr will still be NULL - */ + /* posix_memalign doesn't modify ptr on error: ptr will still be NULL and + * so we will return MAP_FAILED with no need to check explicitly the value + * returned by posix_memalign */ posix_memalign(&ptr, OCAML_SOLO5_PAGESIZE, len); } else { if ((flags & MAP_FIXED) != 0) { From 030a379d47c0995e4c3ac652d6892b46caa942fa Mon Sep 17 00:00:00 2001 From: Pierre Alain Date: Fri, 22 Nov 2024 17:44:50 +0100 Subject: [PATCH 86/92] specify the source for constants macros --- nolibc/include/errno.h | 18 +++++++++++------- nolibc/include/fcntl.h | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index 72591d77..7a928af5 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -2,18 +2,22 @@ #define _ERRNO_H extern int errno; -#define EBADF 9 /* Bad file number */ -#define EAGAIN 11 /* Resource temporarily unavailable */ + +/* The following values are taken from: + * https://github.com/openbsd/src/blob/master/sys/sys/errno.h + */ #define ENOENT 2 /* No such file or directory */ +#define EINTR 4 /* Interrupted system call */ +#define EBADF 9 /* Bad file number */ #define ENOMEM 12 /* Out of memory */ #define EBUSY 16 /* Device or resource busy */ #define EINVAL 22 /* Invalid argument */ #define EMFILE 24 /* Too many open files */ -#define ERANGE 34 /* Math result not representable */ -#define ENOSYS 38 /* Invalid system call number */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define EINTR 4 /* Interrupted system call */ #define EPIPE 32 /* Broken pipe */ -#define ECONNRESET 104 /* Connection reset by peer */ +#define ERANGE 34 /* Math result not representable */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOSYS 78 /* Invalid system call number */ +#define EOVERFLOW 87 /* Value too large for defined data type */ #endif diff --git a/nolibc/include/fcntl.h b/nolibc/include/fcntl.h index 88c292cb..568b65dd 100644 --- a/nolibc/include/fcntl.h +++ b/nolibc/include/fcntl.h @@ -3,12 +3,16 @@ int fcntl(int, int, ...); int open(const char *, int, ...); -#define O_RDONLY 00000000 -#define O_WRONLY 00000001 -#define O_RDWR 00000002 -#define O_CREAT 00000100 -#define O_EXCL 00000200 -#define O_TRUNC 00001000 -#define O_APPEND 00002000 + +/* The following values are taken from: + * https://github.com/openbsd/src/blob/master/sys/sys/fcntl.h + */ +#define O_RDONLY 0x0000 /* open for reading only */ +#define O_WRONLY 0x0001 /* open for writing only */ +#define O_RDWR 0x0002 /* open for reading and writing */ +#define O_APPEND 0x0008 /* set append mode */ +#define O_CREAT 0x0200 /* create if nonexistent */ +#define O_TRUNC 0x0400 /* truncate to zero length */ +#define O_EXCL 0x0800 /* error if already exists */ #endif From a47d30672daf9dfd83d6bf510b930e06f874266a Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 25 Nov 2024 19:24:10 +0100 Subject: [PATCH 87/92] Define `strerror_r` using OpenBSD `sys_errlist` `strerror_r` is used by the runtime to render some system errors so implement it to get useful information in such cases --- LICENSE | 32 +++++++++++++++++++++ nolibc/Makefile | 1 + nolibc/errlist.c | 64 +++++++++++++++++++++++++++++++++++++++++ nolibc/include/errno.h | 35 +++++++++++----------- nolibc/include/string.h | 2 +- nolibc/strerror_r.c | 19 ++++++++++++ nolibc/stubs.c | 1 - 7 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 nolibc/errlist.c create mode 100644 nolibc/strerror_r.c diff --git a/LICENSE b/LICENSE index 84e2736a..d45d80a8 100644 --- a/LICENSE +++ b/LICENSE @@ -81,6 +81,38 @@ SUCH DAMAGE. ---------------------------------------------------------------------- +The file errlist.c in the nolibc/ directory is derived from OpenBSD, +licensed under the following BSD license: + +Copyright (c) 1982, 1985, 1993 + The Regents of the University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +---------------------------------------------------------------------- + The file dtoa.c in the nolibc/ directory is licensed under the following MIT license: diff --git a/nolibc/Makefile b/nolibc/Makefile index d5dfa46a..9ecd3aa1 100644 --- a/nolibc/Makefile +++ b/nolibc/Makefile @@ -16,6 +16,7 @@ CFLAGS+=$(FREESTANDING_CFLAGS) OBJS=assert.o \ ctype.o \ dtoa.o \ + errlist.o strerror_r.o \ memchr.o memcmp.o memcpy.o memmove.o memset.o \ strcmp.o strlen.o strnlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \ strstr.o strncmp.o puts.o \ diff --git a/nolibc/errlist.c b/nolibc/errlist.c new file mode 100644 index 00000000..f714a524 --- /dev/null +++ b/nolibc/errlist.c @@ -0,0 +1,64 @@ +/* This code is mostly an extract from OpenBSD sources, keeping only the needed + * errno values + * + * NOTE: the list of errors must be kept in sync with errno.h */ + +/* + * Copyright (c) 1982, 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +const char *const sys_errlist[] = { + "Undefined error: 0", /* ENOERROR */ + "No such file or directory", /* ENOENT */ + "Interrupted system call", /* EINTR */ + "Bad file descriptor", /* EBADF */ + "Cannot allocate memory", /* ENOMEM */ + "Device busy", /* EBUSY */ + "Invalid argument", /* EINVAL */ + "Too many open files", /* EMFILE */ + "Broken pipe", /* EPIPE */ + +/* math software */ + "Result too large", /* ERANGE */ + +/* non-blocking and interrupt i/o */ + "Resource temporarily unavailable", /* EAGAIN */ + +/* ipc/network software -- operational errors */ + "Connection reset by peer", /* ECONNRESET */ + + "Function not implemented", /* ENOSYS */ + /* EOVERFLOW */ + "Value too large to be stored in data type", +}; + +static_assert((sizeof sys_errlist/sizeof sys_errlist[0]) == NB_ERRORS, + "errlist.c and errno.h are out of sync"); diff --git a/nolibc/include/errno.h b/nolibc/include/errno.h index 7a928af5..eb99d807 100644 --- a/nolibc/include/errno.h +++ b/nolibc/include/errno.h @@ -3,21 +3,24 @@ extern int errno; -/* The following values are taken from: - * https://github.com/openbsd/src/blob/master/sys/sys/errno.h - */ -#define ENOENT 2 /* No such file or directory */ -#define EINTR 4 /* Interrupted system call */ -#define EBADF 9 /* Bad file number */ -#define ENOMEM 12 /* Out of memory */ -#define EBUSY 16 /* Device or resource busy */ -#define EINVAL 22 /* Invalid argument */ -#define EMFILE 24 /* Too many open files */ -#define EPIPE 32 /* Broken pipe */ -#define ERANGE 34 /* Math result not representable */ -#define EAGAIN 35 /* Resource temporarily unavailable */ -#define ECONNRESET 54 /* Connection reset by peer */ -#define ENOSYS 78 /* Invalid system call number */ -#define EOVERFLOW 87 /* Value too large for defined data type */ +/* This list of errors must be kept in sync with errlist.c */ + +#define ENOERROR 0 /* Actual error codes should be > 0 */ + +#define ENOENT 1 +#define EINTR 2 +#define EBADF 3 +#define ENOMEM 4 +#define EBUSY 5 +#define EINVAL 6 +#define EMFILE 7 +#define EPIPE 8 +#define ERANGE 9 +#define EAGAIN 10 +#define ECONNRESET 11 +#define ENOSYS 12 +#define EOVERFLOW 13 + +#define NB_ERRORS 14 #endif diff --git a/nolibc/include/string.h b/nolibc/include/string.h index da7bc6d5..5f5b04c9 100644 --- a/nolibc/include/string.h +++ b/nolibc/include/string.h @@ -12,6 +12,7 @@ int strcmp(const char *, const char *); size_t strlen(const char *); size_t strnlen(const char *, size_t); char *strerror(int); +int strerror_r(int errnum, char *buf, size_t buflen); /* * The following definitions are not required by the OCaml runtime, but are * needed to build the freestanding version of GMP used by Mirage. @@ -27,7 +28,6 @@ int strncmp(const char*, const char*, size_t); /* TODO(dinosaure): we must track where they are used to know if we need * to implement them or not. */ -int strerror_r(int errnum, char *buf, size_t buflen); char *strdup(const char *); #endif diff --git a/nolibc/strerror_r.c b/nolibc/strerror_r.c new file mode 100644 index 00000000..620fa14a --- /dev/null +++ b/nolibc/strerror_r.c @@ -0,0 +1,19 @@ +#include +#include +#include + +extern const char *const sys_errlist[]; + +int strerror_r(int num, char *buf, size_t buflen) +{ + if (num < 0 || num >= NB_ERRORS) { + errno = EINVAL; + return EINVAL; + } + if (snprintf(buf, buflen, "%s", sys_errlist[num]) >= (int)buflen) { + errno = ERANGE; + return ERANGE; + } + + return 0; +} diff --git a/nolibc/stubs.c b/nolibc/stubs.c index 8e73125d..f33cd909 100644 --- a/nolibc/stubs.c +++ b/nolibc/stubs.c @@ -144,4 +144,3 @@ STUB_ABORT(pthread_detach); STUB_IGNORE(int, sigfillset, 0); STUB_ABORT(sigwait); STUB_ABORT(usleep); -STUB_ABORT(strerror_r); From 856daded2f4f70ec87147398c390ae4ee99dab40 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 25 Nov 2024 19:11:58 +0100 Subject: [PATCH 88/92] Drop `strdup` `strdup` is not used in the OCaml runtime, as it is explicitly reimplemented to use the runtime allocator --- nolibc/include/string.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nolibc/include/string.h b/nolibc/include/string.h index 5f5b04c9..7dec8cd5 100644 --- a/nolibc/include/string.h +++ b/nolibc/include/string.h @@ -26,8 +26,4 @@ char *strstr(const char *, const char *); */ int strncmp(const char*, const char*, size_t); -/* TODO(dinosaure): we must track where they are used to know if we need - * to implement them or not. */ -char *strdup(const char *); - #endif From e5071c3f83eea3074581ee2297c1732bd2ecfd74 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 25 Nov 2024 19:09:27 +0100 Subject: [PATCH 89/92] Add a SOLO5TEST variable to have multiple examples --- example/dune | 3 +++ example/{main.ml => main.hello.ml} | 0 2 files changed, 3 insertions(+) rename example/{main.ml => main.hello.ml} (100%) diff --git a/example/dune b/example/dune index f6b3eb8b..95bfd815 100644 --- a/example/dune +++ b/example/dune @@ -5,6 +5,9 @@ (language c) (names startup manifest))) +(rule + (copy main.%{env:SOLO5TEST=hello}.ml main.ml)) + (rule (targets manifest.c) (deps manifest.json) diff --git a/example/main.ml b/example/main.hello.ml similarity index 100% rename from example/main.ml rename to example/main.hello.ml From 33f75ccafa4041e43d3f559910d00ca8433bf401 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 25 Nov 2024 19:10:02 +0100 Subject: [PATCH 90/92] Add an example test that intentionnally fails --- example/main.sysfail.ml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 example/main.sysfail.ml diff --git a/example/main.sysfail.ml b/example/main.sysfail.ml new file mode 100644 index 00000000..9a925c5b --- /dev/null +++ b/example/main.sysfail.ml @@ -0,0 +1,3 @@ +(** An example to show what happens when doing [Sys.chdir] in a Unikernel *) + +let () = Sys.chdir "/tmp" From 6ed39012722260a684658d68b283536a1770d8f0 Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Mon, 25 Nov 2024 19:11:17 +0100 Subject: [PATCH 91/92] Run the sysfail example in CI --- .github/workflows/test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac20731c..bc44d7fd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,6 +23,11 @@ jobs: run: MODE=spt opam exec -- dune build --root example - name: Run example with spt run: opam exec -- solo5-spt example/_build/solo5/main.exe + - name: Compile a failing example with spt + run: MODE=spt SOLO5TEST=sysfail opam exec -- dune build --root example + - name: Run a failing example with spt + run: | + ! opam exec -- solo5-spt example/_build/solo5/main.exe - name: Compile example with virtio run: MODE=virtio opam exec -- dune build --root example - name: Compile example with muen From 75631e13076e44b95b97ec3efe6c58d3bad1f95f Mon Sep 17 00:00:00 2001 From: Samuel Hym Date: Tue, 26 Nov 2024 12:34:14 +0100 Subject: [PATCH 92/92] Update the supported compiler version to 5.2.1 in README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b1726ff..60a57194 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ Run: `solo5-hvt _build/solo5/main.exe` ## Supported compiler versions -Tested against OCaml 5.0. Other versions may require changing `configure.sh`. +Tested against OCaml 5.2.1. Other versions would require specific patches (see +the `patches` directory). ## Porting to a different (uni)kernel base layer