diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..f087b429e2f81a9f37b28a8308e2210f84df6c9b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.tar.gz filter=lfs diff=lfs merge=lfs -text diff --git a/.lfconfig b/.lfconfig new file mode 100644 index 0000000000000000000000000000000000000000..d772ea4026334d7a85382d2c893ac293768fe254 --- /dev/null +++ b/.lfconfig @@ -0,0 +1,2 @@ +[lfs] + url = https://artlfs.openeuler.openatom.cn/src-openEuler/ocaml diff --git a/.lfsconfig b/.lfsconfig new file mode 100644 index 0000000000000000000000000000000000000000..d772ea4026334d7a85382d2c893ac293768fe254 --- /dev/null +++ b/.lfsconfig @@ -0,0 +1,2 @@ +[lfs] + url = https://artlfs.openeuler.openatom.cn/src-openEuler/ocaml diff --git a/0001-Don-t-add-rpaths-to-libraries.patch b/0001-Don-t-add-rpaths-to-libraries.patch index 622ba2f6047b497368c3c8d3384bfea0a658db15..b5735bd8f7e29767c7c4c86c6e3e14b88af2a9a9 100644 --- a/0001-Don-t-add-rpaths-to-libraries.patch +++ b/0001-Don-t-add-rpaths-to-libraries.patch @@ -1,28 +1,25 @@ -From 23f2e84d360208759c7d82b7ff795770ce6cf0b2 Mon Sep 17 00:00:00 2001 +From 507a1382cb82160c2a6cfc0ea5bcb3e33ece7307 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 24 Jun 2014 10:00:15 +0100 -Subject: [PATCH 1/3] Don't add rpaths to libraries. +Subject: [PATCH 1/2] Don't add rpaths to libraries. --- - utils/config.mlp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) + configure.ac | 2 -- + 1 file changed, 2 deletions(-) -diff --git a/utils/config.mlp b/utils/config.mlp -index f758a9b..ee17a73 100644 ---- a/utils/config.mlp -+++ b/utils/config.mlp -@@ -54,8 +54,8 @@ let native_c_compiler = - c_compiler ^ " " ^ ocamlopt_cflags ^ " " ^ ocamlopt_cppflags - let native_c_libraries = "%%NATIVECCLIBS%%" - let native_pack_linker = "%%PACKLD%%" --let default_rpath = "%%RPATH%%" --let mksharedlibrpath = "%%MKSHAREDLIBRPATH%%" -+let default_rpath = "" -+let mksharedlibrpath = "" - let ar = "%%ARCMD%%" - let supports_shared_libraries = %%SUPPORTS_SHARED_LIBRARIES%% - let mkdll, mkexe, mkmaindll = - ---- -2.32.0 +diff --git a/configure.ac b/configure.ac +index 0c9d63859a..48aa9f0a29 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1221,8 +1221,6 @@ AS_IF([test x"$enable_shared" != "xno"], + [[*-*-openbsd7.[3-9]|*-*-openbsd[89].*]], + [mkdll_flags="${mkdll_flags} -Wl,--no-execute-only"]) + oc_ldflags="$oc_ldflags -Wl,-E" +- rpath="-Wl,-rpath," +- mksharedlibrpath="-Wl,-rpath," + natdynlinkopts="-Wl,-E" + supports_shared_libraries=true], + [mkdll='shared-libs-not-available']) +-- +2.44.0 diff --git a/0002-configure-Allow-user-defined-C-compiler-flags.patch b/0002-configure-Allow-user-defined-C-compiler-flags.patch index 2e5813a2e5cda313d6ba7349e0e2a34c2c179baf..9894bc3d738917840e256d328c36515ff8e58fea 100644 --- a/0002-configure-Allow-user-defined-C-compiler-flags.patch +++ b/0002-configure-Allow-user-defined-C-compiler-flags.patch @@ -1,27 +1,35 @@ -From 9966786a7389dc6621f2bc2dce7c690c5a38b67d Mon Sep 17 00:00:00 2001 +From edd903fc73b98eb784b307a47110985967cb1d09 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:44:18 +0100 -Subject: [PATCH 2/3] configure: Allow user defined C compiler flags. +Subject: [PATCH 2/2] configure: Allow user defined C compiler flags. --- - configure.ac | 4 ++++ - 1 file changed, 4 insertions(+) + configure.ac | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac -index 3698c7cbf..e2a3cbea0 100644 +index 48aa9f0a29..fc29c88f50 100644 --- a/configure.ac +++ b/configure.ac -@@ -669,6 +669,10 @@ AS_CASE([$host], - internal_cflags="$cc_warnings"], - [common_cflags="-O"])]) +@@ -925,6 +925,10 @@ AS_CASE([$ocaml_cc_vendor], + internal_cflags="$cc_warnings"], + [common_cflags="-O"]) +# Allow CFLAGS and LDFLAGS to be added. +common_cflags="$common_cflags $CFLAGS" +cclibs="$cclibs $LDFLAGS" + - internal_cppflags="-DCAML_NAME_SPACE $internal_cppflags" - # Enable SSE2 on x86 mingw to avoid using 80-bit registers. + AS_CASE([$host], + [i686-*-mingw32*], +@@ -2708,7 +2712,7 @@ AC_CONFIG_COMMANDS_PRE([ + [mkexedebugflag="${mkexe_ldflags_prefix}${mkexedebugflag}"]) + mkdll_ldflags="" + AS_IF([test -n "${LDFLAGS}"], +- [for flag in ${LDFLAGS}; do ++ [for flag in "${LDFLAGS}"; do + mkdll_ldflags="${mkdll_ldflags} ${mkexe_ldflags_prefix}${flag}" + done + mkdll_ldflags_exp="$mkdll_ldflags"]) -- -2.32.0 - +2.44.0 diff --git a/0004-add-loongarch64-native-support.patch b/0004-add-loongarch64-native-support.patch index b9d1ad8cda2dbb2bd3bece94fcc3020f47f93af3..372a675d39e7648b9f829c0ec24e75f998f5e34e 100644 --- a/0004-add-loongarch64-native-support.patch +++ b/0004-add-loongarch64-native-support.patch @@ -4,21 +4,21 @@ Date: Sat, 8 Jul 2023 17:01:21 +0800 Subject: [PATCH] add loongarch64 native support --- - Makefile | 2 +- - asmcomp/dune | 4 +- - asmcomp/loongarch64/CSE.ml | 38 + - asmcomp/loongarch64/NOTES.md | 13 + - asmcomp/loongarch64/arch.ml | 91 ++ - asmcomp/loongarch64/emit.mlp | 683 +++++++++++++++ - asmcomp/loongarch64/proc.ml | 320 +++++++ - asmcomp/loongarch64/reload.ml | 18 + - asmcomp/loongarch64/scheduling.ml | 21 + - asmcomp/loongarch64/selection.ml | 64 ++ - configure.ac | 9 +- - runtime/caml/stack.h | 5 + - runtime/loongarch64.S | 443 ++++++++++ - testsuite/tools/asmgen_loongarch64.S | 75 ++ - 16 files changed, 2520 insertions(+), 601 deletions(-) + Makefile | 2 +- + asmcomp/dune | 4 +- + asmcomp/loongarch64/CSE.ml | 38 ++ + asmcomp/loongarch64/NOTES.md | 13 + + asmcomp/loongarch64/arch.ml | 91 ++++ + asmcomp/loongarch64/emit.mlp | 683 +++++++++++++++++++++++++++ + asmcomp/loongarch64/proc.ml | 320 +++++++++++++ + asmcomp/loongarch64/reload.ml | 18 + + asmcomp/loongarch64/scheduling.ml | 21 + + asmcomp/loongarch64/selection.ml | 64 +++ + configure.ac | 9 +- + runtime/caml/stack.h | 8 + + runtime/loongarch64.S | 443 +++++++++++++++++ + testsuite/tools/asmgen_loongarch64.S | 75 +++ + 14 files changed, 1784 insertions(+), 5 deletions(-) create mode 100644 asmcomp/loongarch64/CSE.ml create mode 100644 asmcomp/loongarch64/NOTES.md create mode 100644 asmcomp/loongarch64/arch.ml @@ -31,23 +31,23 @@ Subject: [PATCH] add loongarch64 native support create mode 100644 testsuite/tools/asmgen_loongarch64.S diff --git a/Makefile b/Makefile -index 0e92785..d1d9dd7 100644 +index f7fffdc..9c82794 100644 --- a/Makefile +++ b/Makefile -@@ -39,7 +39,7 @@ include stdlib/StdlibModules +@@ -31,7 +31,7 @@ include stdlib/StdlibModules - CAMLC=$(BOOT_OCAMLC) -g -nostdlib -I boot -use-prims runtime/primitives - CAMLOPT=$(OCAMLRUN) ./ocamlopt$(EXE) -g -nostdlib -I stdlib -I otherlibs/dynlink --ARCHES=amd64 i386 arm arm64 power s390x riscv -+ARCHES=amd64 i386 arm arm64 power s390x riscv loongarch64 - INCLUDES=-I utils -I parsing -I typing -I bytecomp -I file_formats \ - -I lambda -I middle_end -I middle_end/closure \ - -I middle_end/flambda -I middle_end/flambda/base_types \ + CAMLC = $(BOOT_OCAMLC) $(BOOT_STDLIBFLAGS) -use-prims runtime/primitives + CAMLOPT=$(OCAMLRUN) ./ocamlopt$(EXE) $(STDLIBFLAGS) -I otherlibs/dynlink +-ARCHES=amd64 arm64 power s390x riscv ++ARCHES=amd64 arm64 power s390x riscv loongarch64 + VPATH = utils parsing typing bytecomp file_formats lambda middle_end \ + middle_end/closure middle_end/flambda middle_end/flambda/base_types \ + asmcomp driver toplevel tools runtime \ diff --git a/asmcomp/dune b/asmcomp/dune -index 1a4d561..1817bc4 100644 +index fb3da10..09bc732 100644 --- a/asmcomp/dune +++ b/asmcomp/dune -@@ -23,6 +23,7 @@ +@@ -22,6 +22,7 @@ (glob_files power/*.ml) (glob_files riscv/*.ml) (glob_files s390x/*.ml)) @@ -55,8 +55,8 @@ index 1a4d561..1817bc4 100644 (action (bash "cp `grep '^ARCH=' %{conf} | cut -d'=' -f2`/*.ml ."))) (rule -@@ -35,7 +36,8 @@ - i386/emit.mlp +@@ -32,7 +33,8 @@ + arm64/emit.mlp power/emit.mlp riscv/emit.mlp - s390x/emit.mlp) @@ -1362,32 +1362,32 @@ index 0000000..cb6ffc5 +let fundecl ~future_funcnames f = + (new selector)#emit_fundecl ~future_funcnames f diff --git a/configure.ac b/configure.ac -index 20f0873..456f836 100644 +index faabd47..cef6a63 100644 --- a/configure.ac +++ b/configure.ac -@@ -1027,7 +1027,8 @@ AS_IF([test x"$supports_shared_libraries" = 'xtrue'], - [aarch64-*-linux*], [natdynlink=true], +@@ -1393,7 +1393,8 @@ AS_IF([test x"$supports_shared_libraries" = 'xtrue'], [aarch64-*-freebsd*], [natdynlink=true], [aarch64-*-openbsd*], [natdynlink=true], + [aarch64-*-netbsd*], [natdynlink=true], - [riscv*-*-linux*], [natdynlink=true])]) + [riscv*-*-linux*], [natdynlink=true], + [loongarch*-*-linux*], [natdynlink=true])]) AS_CASE([$enable_native_toplevel,$natdynlink], [yes,false], -@@ -1144,7 +1145,9 @@ AS_CASE([$host], +@@ -1523,7 +1524,9 @@ AS_CASE([$host], [x86_64-*-cygwin*], - [arch=amd64; system=cygwin], + [has_native_backend=yes; arch=amd64; system=cygwin], [riscv64-*-linux*], -- [arch=riscv; model=riscv64; system=linux] -+ [arch=riscv; model=riscv64; system=linux], +- [has_native_backend=yes; arch=riscv; model=riscv64; system=linux] ++ [has_native_backend=yes; arch=riscv; model=riscv64; system=linux], + [loongarch64-*-linux*], -+ [arch=loongarch64; system=linux] ++ [has_native_backend=yes; arch=loongarch64; system=linux] ) - AS_IF([test x"$enable_native_compiler" = "xno"], -@@ -1239,7 +1242,7 @@ default_aspp="$CC -c" - AS_CASE([$as_target,$ocaml_cv_cc_vendor], + AS_CASE([$arch], +@@ -1637,7 +1640,7 @@ default_aspp="$CC -c" + AS_CASE([$as_target,$ocaml_cc_vendor], [*-*-linux*,gcc-*], [AS_CASE([$as_cpu], - [x86_64|arm*|aarch64*|i[[3-6]]86|riscv*], @@ -1396,21 +1396,24 @@ index 20f0873..456f836 100644 [i686-pc-windows,*], [default_as="ml -nologo -coff -Cp -c -Fo" diff --git a/runtime/caml/stack.h b/runtime/caml/stack.h -index 9c182ee..e49c78d 100644 +index 1d3f28d..260f4b9 100644 --- a/runtime/caml/stack.h +++ b/runtime/caml/stack.h -@@ -75,6 +75,11 @@ - #define Callback_link(sp) ((struct caml_context *)((sp) + 16)) +@@ -94,6 +94,14 @@ + #define Stack_header_size 32 #endif +#ifdef TARGET_loongarch64 ++#define Wosize_gc_regs (2 + 22 /* int regs */ + 20 /* float regs */) +#define Saved_return_address(sp) *((intnat *)((sp) - 8)) -+#define Callback_link(sp) ((struct caml_context *)((sp) + 16)) ++#define First_frame(sp) ((sp) + 16) ++#define Saved_gc_regs(sp) (*(value **)((sp) + 24)) ++#define Stack_header_size 32 +#endif + - /* Structure of OCaml callback contexts */ - - struct caml_context { + /* Declaration of variables used in the asm code */ + extern value * caml_globals[]; + extern intnat caml_globals_inited; diff --git a/runtime/loongarch64.S b/runtime/loongarch64.S new file mode 100644 index 0000000..5034e8a @@ -1942,6 +1945,5 @@ index 0000000..ca5ef1b +caml_c_call: + jr $t2 -- -2.42.0 - +2.49.0 diff --git a/4.14.2.tar.gz b/4.14.2.tar.gz deleted file mode 100644 index 7f99c024cdb84c988eaa0afb221d98244dddadc7..0000000000000000000000000000000000000000 Binary files a/4.14.2.tar.gz and /dev/null differ diff --git a/macros.ocaml-rpm b/macros.ocaml-rpm new file mode 100644 index 0000000000000000000000000000000000000000..b25cd47f417cc827389c5353434044bcbbc10190 --- /dev/null +++ b/macros.ocaml-rpm @@ -0,0 +1,69 @@ +# Make %files lists from an installed tree of files. +# Options: +# -s: separate packaging; every subdirectory of %%{ocamldir}, except stublibs, +# is placed in its own package. This option requires the existence of opam +# *.install files in the build tree. +# -n: suppress creation of a devel subpackage. +%ocaml_files(sn) %{__python3} /usr/lib/rpm/openEuler/ocaml_files.py %{-s} %{-n} %{buildroot} %{ocamldir} + +# Internal macro holding the common parts of ocaml_install and dune_install +%ocaml_install_common(sn) %{expand: +rm -rf %{buildroot}%{_prefix}/doc +mlis=$(find %{buildroot}%{_libdir}/ocaml -name '*.mli') +rm -f ${mlis//.mli/.ml} +%ocaml_files %{-s} %{-n}} + +# Install files listed in opam *.install files. +# Options: +# -s: separate packaging; every subdirectory of %%{ocamldir}, except stublibs, +# is placed in its own package. +# -n: suppress creation of a devel subpackage. +%ocaml_install(sn) %{expand: +%{__python3} /usr/lib/rpm/openEuler/ocaml_files.py -i %{-s} %{-n} %{buildroot} %{ocamldir} +%ocaml_install_common %{-s} %{-n}} + +# Add smp_mflags to arguments if no -j release option is given. +# Add --release to arguments if no -p or --release option is given. +# Add --verbose to arguments if it is not given. +%dune_add_flags(-) %{lua: + has_j = false + has_p = false + has_v = false + for _, flag in pairs(arg) do + if flag:find("^-j") then + has_j = true + elseif flag:find("^-p") or flag:find("^--release)") then + has_p = true + elseif flag:find("^--verbose") then + has_v = true + end + end + if not has_j then + table.insert(arg, 1, rpm.expand("%{?_smp_mflags}")) + end + if not has_p then + table.insert(arg, 1, "--release") + end + if not has_v then + table.insert(arg, 1, "--verbose") + end + print(table.concat(arg, " ")) +} + +# Build with dune +%dune_build(-) dune build %{dune_add_flags %*} + +# Run tests with dune +%dune_check(-) dune runtest %{dune_add_flags %*} + +# Install with dune +# Options: +# -s: separate packaging; every subdirectory of %%{ocamldir}, except stublibs, +# is placed in its own package. +# -n: suppress creation of a devel subpackage. +%dune_install(sn) %{expand: +dune install --destdir=%{buildroot} %{dune_add_flags %*} +if [ -d _build/default/_doc/_html ]; then + find _build/default/_doc/_html -name .dune-keep -delete +fi +%ocaml_install_common %{-s} %{-n}} diff --git a/macros.ocaml-srpm b/macros.ocaml-srpm new file mode 100644 index 0000000000000000000000000000000000000000..e7a04982728bd2a2f7d7775a1f8e2d15dbbc5c98 --- /dev/null +++ b/macros.ocaml-srpm @@ -0,0 +1,55 @@ +# Note that OCaml is compiled on all architectures. However +# on some (rare) architectures, only bytecode compilation is +# available. Use these macros to find out if native code +# compilation is available on a particular architecture. + +# Architectures that support the OCaml native code compiler. +%ocaml_native_compiler aarch64 %{power64} riscv64 s390x x86_64 + +# Architectures that support native dynamic linking of OCaml code. +%ocaml_natdynlink aarch64 %{power64} riscv64 s390x x86_64 + +# Architectures that support profiling of native code (ocamlopt -p). +# This was removed in OCaml 4.09. +# https://github.com/ocaml/ocaml/pull/2314 +%ocaml_native_profiling %{nil} + +# Toplevel OCaml directory +%ocamldir %{_libdir}/ocaml + +# Common elements for all OCaml packages. +# +# ExcludeArch: OCaml packages have not been built on i686 since OCaml 5 was +# introduced in Fedora 39. +# -d: most OCaml packages have no ELF objects when built on a bytecode-only +# architecture, so debuginfo generation is suppressed. Use this flag to +# enable a debuginfo package on such architectures; i.e., when the package +# contains an ELF object even on bytecode-only architectures. +%ocaml_pkg(d) %{lua: + print("ExcludeArch: %{ix86}\\n") + if not opt.d then + local arch = rpm.expand("%{_target_cpu}") + local native = rpm.expand("%{ocaml_native_compiler}") + if not string.find(native, arch) then + rpm.define('debug_package %{nil}') + end + end +} + +# Generate %package and %files definitions for a doc subpackage, +# containing content generated by odoc. +# Use on the top-level only, preferably just before %prep. +# +# Options: +# -L: specify the license file name. Example: +# %odoc_package -L LICENSE +%odoc_package(L:) %{expand: +%package doc +BuildArch: noarch +BuildRequires: ocaml-odoc +Summary: Documentation for %{name} +%description doc +Developer documentation for %{name}. +%files doc +%doc _build/default/_doc/_html/* +%{?-L:%%license %{-L*} %*}} diff --git a/ocaml-5.3.0.tar.gz b/ocaml-5.3.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a94b8b6beccdd6d1b4c86779d08fec7fb0a7406b --- /dev/null +++ b/ocaml-5.3.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb9eab2f21758d3cfb1e78c7f83f0b4dd6302824316aba4abee047a5a4f85029 +size 6239856 diff --git a/ocaml.spec b/ocaml.spec index 80451f4fcf3a12e330c88cbc5932df754af33bf7..4904b487e6cdab40196c3e3e74edc36079841f65 100644 --- a/ocaml.spec +++ b/ocaml.spec @@ -3,12 +3,15 @@ %global natdynlink 1 Name: ocaml -Version: 4.14.2 +Version: 5.3.0 Release: 1 Summary: OCaml compiler and programming environment License: LGPL-2.1-only URL: https://www.ocaml.org -Source0: https://github.com/ocaml/ocaml/archive/refs/tags/%{version}.tar.gz +Source0: https://github.com/ocaml/ocaml/archive/%{version}/%{name}-%{version}.tar.gz +Source1: ocaml_files.py +Source2: macros.ocaml-rpm +Source3: macros.ocaml-srpm Patch0001: 0001-Don-t-add-rpaths-to-libraries.patch Patch0002: 0002-configure-Allow-user-defined-C-compiler-flags.patch @@ -19,6 +22,7 @@ BuildRequires: gcc binutils-devel ncurses-devel gdbm-devel gawk perl-interpret BuildRequires: util-linux chrpath autoconf annobin make Requires: gcc util-linux %{_vendor}-rpm-config +Requires: ocaml-srpm-macros Provides: bundled(md5-plumb) ocaml(runtime) = %{version} Provides: ocaml(compiler) = %{version} @@ -27,7 +31,7 @@ Obsoletes: %{name}-runtime < %{version}-%{release} Provides: %{name}-ocamldoc = %{version}-%{release} Obsoletes: %{name}-ocamldoc < %{version}-%{release} -%global __ocaml_requires_opts -c -f '%{buildroot}%{_bindir}/ocamlrun %{buildroot}%{_bindir}/ocamlobjinfo.byte' +%global __ocaml_requires_opts -c -f '%{buildroot}%{_bindir}/ocamlrun %{buildroot}%{_bindir}/ocamlobjinfo.byte' -i Dynlink_cmo_format -i Dynlink_cmxs_format %global __ocaml_provides_opts -f '%{buildroot}%{_bindir}/ocamlrun %{buildroot}%{_bindir}/ocamlobjinfo.byte' %description @@ -54,13 +58,36 @@ and compiler-libs for development of some OCaml applications. %package help Summary: Help files for %{name} BuildArch: noarch -Requires: ocaml = %{version}-%{release} -Provides: %{name}-docs = %{version}-%{release} -Obsoletes: %{name}-docs < %{version}-%{release} +Requires: ocaml = %{version}-%{release} +Provides: %{name}-docs = %{version}-%{release} +Obsoletes: %{name}-docs < %{version}-%{release} %description help Help files for %{name} +%package rpm-macros +License: LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception AND BSD-3-Clause +Summary: RPM macros for building OCaml packages +BuildArch: noarch +Requires: ocaml = %{version}-%{release} +Requires: python3 + + +%description rpm-macros +This package contains macros that are useful for building OCaml RPMs. + +%package srpm-macros +License: GPL-2.0-or-later +Summary: OCaml architecture macros +BuildArch: noarch +Requires: ocaml = %{version}-%{release} + + +%description srpm-macros +This package contains macros needed by RPM in order to build +SRPMS. It does not pull in any other OCaml dependencies. + + %prep %autosetup -n %{name}-%{version} -p1 autoconf --force @@ -115,6 +142,13 @@ find %{buildroot} \( -name '*.cmt' -o -name '*.cmti' \) -a -delete rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata +mkdir -p $RPM_BUILD_ROOT%{rpmmacrodir} +install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{rpmmacrodir}/macros.ocaml-rpm +install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{rpmmacrodir}/macros.ocaml-srpm + +mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/openEuler +install -m 0644 %{SOURCE1} $RPM_BUILD_ROOT%{_rpmconfigdir}/openEuler + %files %license LICENSE %{_bindir}/ocaml @@ -135,40 +169,28 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata # bytecode versions %{_bindir}/ocamlc.byte -%{_bindir}/ocamlcp.byte %{_bindir}/ocamldep.byte %{_bindir}/ocamllex.byte -%{_bindir}/ocamlmklib.byte -%{_bindir}/ocamlmktop.byte %{_bindir}/ocamlobjinfo.byte -%{_bindir}/ocamloptp.byte -%{_bindir}/ocamlprof.byte %if %{native_compiler} # native code versions %{_bindir}/ocamlc.opt -%{_bindir}/ocamlcp.opt %{_bindir}/ocamldep.opt %{_bindir}/ocamllex.opt -%{_bindir}/ocamlmklib.opt -%{_bindir}/ocamlmktop.opt %{_bindir}/ocamlobjinfo.opt -%{_bindir}/ocamloptp.opt -%{_bindir}/ocamlprof.opt %{_bindir}/ocamlopt %{_bindir}/ocamlopt.byte %{_bindir}/ocamlopt.opt %endif -%{_libdir}/ocaml/camlheader -%{_libdir}/ocaml/camlheader_ur %{_libdir}/ocaml/expunge %{_libdir}/ocaml/ld.conf %{_libdir}/ocaml/Makefile.config %{_libdir}/ocaml/*.a %if %{natdynlink} -%{_libdir}/ocaml/*.cmxs +%{_libdir}/ocaml/{runtime_events,str,unix}/*.cmxs %endif %if %{native_compiler} @@ -179,13 +201,15 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata %endif %{_libdir}/ocaml/*.mli +%{_libdir}/ocaml/sys.ml.in %{_libdir}/ocaml/libcamlrun_shared.so -%{_libdir}/ocaml/threads/*.mli +%{_libdir}/ocaml/{dynlink,runtime_events,str,threads,unix}/*.mli %if %{native_compiler} -%{_libdir}/ocaml/threads/*.a -%{_libdir}/ocaml/threads/*.cmxa -%{_libdir}/ocaml/threads/*.cmx +%{_libdir}/ocaml/{dynlink,runtime_events,str,threads,unix}/*.a +%{_libdir}/ocaml/{dynlink,runtime_events,str,threads,unix}/*.cmxa +%{_libdir}/ocaml/{dynlink,profiling,runtime_events,str,threads,unix}/*.cmx +%{_libdir}/ocaml/profiling/*.o %endif %{_libdir}/ocaml/caml @@ -199,9 +223,29 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata %{_libdir}/ocaml/*.cmi %{_libdir}/ocaml/*.cma %{_libdir}/ocaml/stublibs -%{_libdir}/ocaml/camlheaderi -%{_libdir}/ocaml/camlheaderd +%dir %{_libdir}/ocaml/dynlink +%{_libdir}/ocaml/dynlink/META +%{_libdir}/ocaml/dynlink/*.cmi +%{_libdir}/ocaml/dynlink/*.cma +%dir %{_libdir}/ocaml/profiling +%{_libdir}/ocaml/profiling/*.cmo +%{_libdir}/ocaml/profiling/*.cmi +%dir %{_libdir}/ocaml/runtime_events +%{_libdir}/ocaml/runtime_events/META +%{_libdir}/ocaml/runtime_events/*.cmi +%{_libdir}/ocaml/runtime_events/*.cma +%{_libdir}/ocaml/runtime-launch-info +%{_libdir}/ocaml/stdlib +%dir %{_libdir}/ocaml/str +%{_libdir}/ocaml/str/META +%{_libdir}/ocaml/str/*.cmi +%{_libdir}/ocaml/str/*.cma +%dir %{_libdir}/ocaml/unix +%{_libdir}/ocaml/unix/META +%{_libdir}/ocaml/unix/*.cmi +%{_libdir}/ocaml/unix/*.cma %dir %{_libdir}/ocaml/threads +%{_libdir}/ocaml/threads/META %{_libdir}/ocaml/threads/*.cmi %{_libdir}/ocaml/threads/*.cma %{_libdir}/ocaml/%{_vendor}-ocaml-release @@ -221,6 +265,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata # compiler-libs %dir %{_libdir}/ocaml/compiler-libs +%{_libdir}/ocaml/compiler-libs/META %{_libdir}/ocaml/compiler-libs/*.mli %{_libdir}/ocaml/compiler-libs/*.cmi %{_libdir}/ocaml/compiler-libs/*.cmo @@ -233,12 +278,32 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/ocaml/eventlog_metadata %{_libdir}/ocaml/compiler-libs/*.o %endif +%files rpm-macros +%{rpmmacrodir}/macros.ocaml-rpm +%{_rpmconfigdir}/openEuler/ocaml_files.py + +%files srpm-macros +%{rpmmacrodir}/macros.ocaml-srpm %files help %{_mandir}/man1/* %{_mandir}/man3/* %changelog +* Fri Apr 18 2025 yaoxin <1024769339@qq.com> - 5.3.0-1 +- Update to 5.3.0: + * Syntax for deep effect handlers + * Restored MSVC port + * Re-introduced statistical memory profiling (statmemprof) + * utf-8 encoded Unicode source files and modest support of Unicode identifiers + * More space-efficient implementation of Dynarray + * Improved metadata on the pairs of declarations and definitions for merlin. + * Around 20 new functions in the standard library + * Many fixes and improvements in the runtime + * Improved error messages for first-class modules, functors, labeled arguments, + type clashes. + * Numerous bug fixes + * Fri Oct 11 2024 Funda Wang - 4.14.2-1 - update to 4.14.2 diff --git a/ocaml_files.py b/ocaml_files.py new file mode 100644 index 0000000000000000000000000000000000000000..cf4afd19b0ccbd6216efbda0b4fdf1f165044493 --- /dev/null +++ b/ocaml_files.py @@ -0,0 +1,451 @@ +# Copyright 2022-3, Jerry James +# +# 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 Red Hat 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 COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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. + +import argparse +import os +import shutil +import string +import sys +from collections.abc import Iterable, Iterator +from enum import Enum, auto +from typing import Callable, final + +# Version of this script +version=2 + +# +# BUILDROOT CATEGORIZATION +# + +# Directories to ignore when generating %dir entries +root_dirs: set[str] = { + '/', + '/etc', + '/usr', + '/usr/bin', + '/usr/lib', + '/usr/lib/ocaml', + '/usr/lib/ocaml/caml', + '/usr/lib/ocaml/stublibs', + '/usr/lib/ocaml/threads', + '/usr/lib64', + '/usr/lib64/ocaml', + '/usr/lib64/ocaml/caml', + '/usr/lib64/ocaml/stublibs', + '/usr/lib64/ocaml/threads', + '/usr/libexec', + '/usr/sbin', + '/usr/share', + '/usr/share/doc' +} + +def find_buildroot_toplevel(buildroot: str) -> list[str]: + """Find toplevel files and directories in the buildroot. + + :param str buildroot: path to the buildroot + :return: a list of toplevel files and directories in the buildroot + """ + bfiles: list[str] = [] + for path, dirs, files in os.walk(buildroot): + for i in range(len(dirs) - 1, -1, -1): + d = os.path.join(path, dirs[i])[len(buildroot):] + if d not in root_dirs and not d.startswith('/usr/share/man'): + bfiles.append(d) + del dirs[i] + for f in files: + realfile = os.path.join(path, f)[len(buildroot):] + if realfile.startswith('/usr/share/man'): + bfiles.append(realfile + '*') + else: + bfiles.append(realfile) + return bfiles + +# File suffixes that go into a devel subpackage +dev_suffixes: set[str] = { + 'a', 'cmo', 'cmt', 'cmti', 'cmx', 'cmxa', 'h', 'idl', 'ml', 'mli', 'o' +} + +def is_devel_file(filname: str) -> bool: + """Determine whether a file belongs to a devel subpackage. + + :param str filname: the filename to check + :return: True if the file belongs to a devel subpackage, else False + """ + return (filname == 'dune-package' or filname == 'opam' or + (os.path.splitext(filname)[1][1:] in dev_suffixes + and not filname.endswith('_top_init.ml'))) + +def find_buildroot_all(buildroot: str, devel: bool, add_star: bool) -> list[set[str]]: + """Find all files and directories in the buildroot and optionally + categorize them as 'main' or 'devel'. + + :param Namespace args: parsed command line arguments + :param bool devel: True to split into 'main' and 'devel', False otherwise + :param bool add_star: True to add a star to man page filenames + :return: a list of files and directories, in this order: main files, + main directories, devel files, and devel directories + """ + bfiles: list[set[str]] = [set(), set(), set()] + bdirs: set[str] = set() + for path, dirs, files in os.walk(buildroot): + for d in dirs: + realdir = os.path.join(path, d)[len(buildroot):] + if realdir not in root_dirs and not realdir.startswith('/usr/share/man'): + bdirs.add(realdir) + for f in files: + realfile = os.path.join(path, f)[len(buildroot):] + if devel and is_devel_file(os.path.basename(realfile)): + bfiles[2].add(realfile) + else: + if add_star and realfile.startswith('/usr/share/man'): + bfiles[0].add(realfile + '*') + else: + bfiles[0].add(realfile) + parentdir = os.path.dirname(realfile) + if parentdir in bdirs: + bfiles[1].add(parentdir) + bdirs.remove(parentdir) + # Catch intermediate directories, as in ocaml-mtime + parentdir = os.path.dirname(parentdir) + if parentdir in bdirs: + bfiles[1].add(parentdir) + bdirs.remove(parentdir) + bfiles.append(bdirs) + return bfiles + +# +# INSTALL FILE LEXER AND PARSER +# + +class TokenType(Enum): + """The types of tokens that can appear in an opam *.install file.""" + ERROR = auto() + COLON = auto() + LBRACE = auto() + RBRACE = auto() + LBRACK = auto() + RBRACK = auto() + STRING = auto() + FIELD = auto() + +@final +class InstallFileLexer(Iterator[tuple[TokenType, str]]): + """Convert an opam *.install file into a sequence of tokens.""" + __slots__ = ['index', 'text'] + + def __init__(self, filname: str) -> None: + """Create an opam *.install file lexer. + + :param str filname: the name of the file to read from + """ + self.index = 0 + with open(filname, 'r') as f: + # Limit reads to 4 MB in case this file is bogus. + # Most install files are under 4K. + self.text = f.read(4194304) + + def skip_whitespace(self) -> None: + """Skip over whitespace in the input.""" + while self.index < len(self.text) and \ + (self.text[self.index] == '#' or + self.text[self.index] in string.whitespace): + if self.text[self.index] == '#': + while (self.index < len(self.text) and + self.text[self.index] != '\n' and + self.text[self.index] != '\r'): + self.index += 1 + else: + self.index += 1 + + def __next__(self) -> tuple[TokenType, str]: + """Get the next token from the opam *.install file. + + :return: a pair containing the type and text of the next token + """ + self.skip_whitespace() + if self.index < len(self.text): + ch = self.text[self.index] + if ch == ':': + self.index += 1 + return (TokenType.COLON, ch) + if ch == '{': + self.index += 1 + return (TokenType.LBRACE, ch) + if ch == '}': + self.index += 1 + return (TokenType.RBRACE, ch) + if ch == '[': + self.index += 1 + return (TokenType.LBRACK, ch) + if ch == ']': + self.index += 1 + return (TokenType.RBRACK, ch) + if ch == '"': + start = self.index + 1 + end = start + while end < len(self.text) and self.text[end] != '"': + end += 2 if self.text[end] == '\\' else 1 + self.index = end + 1 + return (TokenType.STRING, self.text[start:end]) + if ch in string.ascii_letters: + start = self.index + end = start + 1 + while (end < len(self.text) and + (self.text[end] == '_' or + self.text[end] in string.ascii_letters)): + end += 1 + self.index = end + return (TokenType.FIELD, self.text[start:end]) + return (TokenType.ERROR, ch) + else: + raise StopIteration + +@final +class InstallFileParser(Iterable[tuple[str, bool, str, str]]): + """Parse opam *.install files.""" + + __slots__ = ['pkgname', 'lexer', 'libdir'] + + def __init__(self, filname: str, libdir: str) -> None: + """Initialize an OCaml .install file parser. + + :param str filname: name of the .install file to parse + :param str libdir: the OCaml library directory + """ + self.pkgname = os.path.splitext(os.path.basename(filname))[0] + self.lexer = InstallFileLexer(filname) + self.libdir = libdir + + def __iter__(self) -> Iterator[tuple[str, bool, str, str]]: + """Parse a .install file. + If there are any parse errors, we assume this file is not really an + opam .install file and abandon the parse. + """ + # Map opam installer names to directories + opammap: dict[str, str] = { + 'lib': os.path.join(self.libdir, self.pkgname), + 'lib_root': self.libdir, + 'libexec': os.path.join(self.libdir, self.pkgname), + 'libexec_root': self.libdir, + 'bin': '/usr/bin', + 'sbin': '/usr/sbin', + 'toplevel': os.path.join(self.libdir, 'toplevel'), + 'share': os.path.join('/usr/share', self.pkgname), + 'share_root': '/usr/share', + 'etc': os.path.join('/etc', self.pkgname), + 'doc': os.path.join('/usr/doc', self.pkgname), + 'stublibs': os.path.join(self.libdir, 'stublibs'), + 'man': '/usr/share/man' + } + + # Parse the file + try: + toktyp, token = next(self.lexer) + while toktyp == TokenType.FIELD: + libname = token + toktyp, token = next(self.lexer) + if toktyp != TokenType.COLON: + return + + toktyp, token = next(self.lexer) + if toktyp != TokenType.LBRACK: + return + + directory = opammap.get(libname) + if not directory: + return + + toktyp, token = next(self.lexer) + while toktyp == TokenType.STRING: + source = token + optional = source[0] == '?' + if optional: + source = source[1:] + nexttp, nexttk = next(self.lexer) + if nexttp == TokenType.LBRACE: + nexttp, nexttk = next(self.lexer) + if nexttp == TokenType.STRING: + filname = os.path.join(directory, nexttk) + bracetp, bractk = next(self.lexer) + if bracetp != TokenType.RBRACE: + return + nexttp, nexttk = next(self.lexer) + else: + return + elif libname == 'man': + index = token.rfind('.') + if index < 0: + return + mandir = os.path.join(directory, 'man' + token[index+1:]) + filname = os.path.join(mandir, os.path.basename(token)) + else: + filname = os.path.join(directory, os.path.basename(token)) + toktyp, token = nexttp, nexttk + yield (self.pkgname, optional, source, filname) + + if toktyp != TokenType.RBRACK: + return + toktyp, token = next(self.lexer) + except StopIteration: + return + +def install_files(buildroot: str, libdir: str) -> None: + """Install the files listed in opam .install files in the buildroot. + + For some projects, there are install files in both the project root + directory and somewhere under "_build", so be careful not to parse the same + install file twice. + + :param str buildroot: path to the buildroot + :param str libdir: the OCaml library directory + """ + install_files = set() + for path, dirs, files in os.walk('.'): + for f in files: + if f.endswith('.install') and f not in install_files: + install_files.add(f) + parser = InstallFileParser(os.path.join(path, f), libdir) + for _, optional, source, filname in parser: + if not optional or os.path.exists(source): + installpath = os.path.join(buildroot, filname[1:]) + os.makedirs(os.path.dirname(installpath), exist_ok=True) + shutil.copy2(source, installpath) + +def get_package_map(buildroot: str, libdir: str, devel: bool) -> dict[str, set[str]]: + """Create a map from package names to installed files from the opam .install + files in the buildroot. + + For some projects, there are install files in both the project root + directory and somewhere under "_build", so be careful not to parse the same + install file twice.""" + + pmap: dict[str, set[str]] = dict() + install_files = set() + + def add_pkg(pkgname: str, filname: str) -> None: + """Add a mapping from a package name to a filename. + + :param str pkgname: the package that acts as the map key + :param str filname: the filename to add to the package set + """ + if pkgname not in pmap: + pmap[pkgname] = set() + pmap[pkgname].add(filname) + + installed = find_buildroot_all(buildroot, devel, False) + for path, dirs, files in os.walk('.'): + for f in files: + if f.endswith('.install') and f not in install_files: + install_files.add(f) + parser = InstallFileParser(os.path.join(path, f), libdir) + for pkgname, _, _, filname in parser: + if filname in installed[0]: + if filname.startswith('/usr/share/man'): + add_pkg(pkgname, filname + '*') + else: + add_pkg(pkgname, filname) + dirname = os.path.dirname(filname) + if dirname in installed[1]: + add_pkg(pkgname, '%dir ' + dirname) + installed[1].remove(dirname) + elif filname in installed[2]: + if filname.startswith('/usr/share/man'): + add_pkg(pkgname + '-devel', filname + '*') + else: + add_pkg(pkgname + '-devel', filname) + dirname = os.path.dirname(filname) + if dirname in installed[3]: + add_pkg(pkgname + '-devel', '%dir ' + dirname) + installed[3].remove(dirname) + return pmap + +# +# MAIN INTERFACE +# + +def ocaml_files(no_devel: bool, separate: bool, install: bool, buildroot: str, + libdir: str) -> None: + """Generate %files lists from an installed buildroot. + + :param bool no_devel: False to split files into a main package and a devel + package + :param bool separate: True to place each OCaml module in an RPM package + :param bool install: True to install files, False to generate %files + :param str buildroot: the installed buildroot + :param str libdir: the OCaml library directory + """ + if install: + install_files(buildroot, libdir) + elif separate: + pkgmap = get_package_map(buildroot, libdir, not no_devel) + for pkg in pkgmap: + with open('.ofiles-' + pkg, 'w') as f: + for entry in pkgmap[pkg]: + f.write(entry + '\n') + elif no_devel: + with open('.ofiles', 'w') as f: + for entry in find_buildroot_toplevel(buildroot): + f.write(entry + '\n') + else: + files = find_buildroot_all(buildroot, True, True) + with open('.ofiles', 'w') as f: + for entry in files[0]: + f.write(entry + '\n') + for entry in files[1]: + f.write('%dir ' + entry + '\n') + with open('.ofiles-devel', 'w') as f: + for entry in files[2]: + f.write(entry + '\n') + for entry in files[3]: + f.write('%dir ' + entry + '\n') + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Support for building OCaml RPM packages') + parser.add_argument('-i', '--install', + action='store_true', + default=False, + help='install files instead of generating %files') + parser.add_argument('-n', '--no-devel', + action='store_true', + default=False, + help='suppress creation of a devel subpackage') + parser.add_argument('-s', '--separate', + action='store_true', + default=False, + help='separate packaging. Each OCaml module is in a distinct RPM package. All modules are in a single RPM package by default.') + parser.add_argument('-v', '--version', + action='version', + version=f'%(prog)s {str(version)}') + parser.add_argument('buildroot', help='RPM build root') + parser.add_argument('libdir', help='OCaml library directory') + args = parser.parse_args() + ocaml_files(args.no_devel, + args.separate, + args.install, + args.buildroot, + args.libdir)