ocaml-rpm-macros/ocaml-rpm-macros.spec
Olaf Hering 63ac6d61e1 - Adjust injection of version into findlib META files
A file VERSION is not handled anymore by dune since 1.11.
  Remove version: from *.opam files, inject version into dune-project

OBS-URL: https://build.opensuse.org/package/show/devel:languages:ocaml/ocaml-rpm-macros?expand=0&rev=48
2021-01-15 10:00:01 +00:00

537 lines
15 KiB
RPMSpec

#
# spec file for package ocaml-rpm-macros
#
# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: ocaml-rpm-macros
Version: 20210114
Release: 0
Summary: RPM macros for building OCaml source packages
License: GPL-2.0-only
Group: Development/Languages/OCaml
URL: https://build.opensuse.org/project/show/devel:languages:ocaml
Source0: ocaml-ocaml.rpm.prov_req.attr.sh
Source1: ocaml-findlib.rpm.prov_req.attr.sh
%define ocaml_standard_library %{_libdir}/ocaml
%define do_opt 0
# macros to be set in prjconf:
#Macros:
#_with_ocaml_force_enable_ocaml_opt 1
#_with_ocaml_force_disable_ocaml_opt 1
#_with_ocaml_make_testsuite 1
#:Macros
%bcond_with ocaml_force_enable_ocaml_opt
%bcond_with ocaml_force_disable_ocaml_opt
%bcond_with ocaml_make_testsuite
%if %{with ocaml_force_enable_ocaml_opt}
%define do_opt 1
%endif
%if %{without ocaml_force_enable_ocaml_opt}
%ifarch %{arm} aarch64 %{ix86} ppc ppc64 ppc64le riscv64 s390x x86_64
%define do_opt 1
%endif
%endif
#
%if %{with ocaml_force_disable_ocaml_opt}
%define do_opt 0
%endif
#
%description
OCaml is a high-level, strongly-typed, functional and object-oriented
programming language from the ML family of languages.
This package contains a set of helper macros to unify common code used
in ocaml spec files.
%prep
%build
%install
# map ocamlobjinfo output to rpm Provides/Requires
# this tag name MUST match what ocaml.spec uses internally
tag="suseocaml"
mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_
%%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh --provides
%%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh --requires
%%__${tag}_magic ^(ELF|Objective caml|OCaml) .*$
%%__${tag}_path .(cma|cmi|cmo|cmx|cmxa|cmxs)$
%%__${tag}_flags magic_and_path
_EOF_
#
tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE0}
# map findlib names to rpm Provides/Requires
tag="suseocamlfind"
mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_
%%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh -prov
%%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh -req
%%__${tag}_path ^%{ocaml_standard_library}/.*/META$|^%{ocaml_standard_library}/META$
_EOF_
#
tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1}
# install OCaml macros
mkdir -vp %{buildroot}%{_rpmmacrodir}
tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
# Guidelines:
# - Providing applications written in OCaml is the main goal of our packaging.
# - Applications written in OCaml are static binaries.
# - A concept of shared libraries does not exist, beside the Dynlink module
# - All binaries go into the main package, in case they are produced.
# - All modules go into the -devel subpackage
# - Helper applications below %{ocaml_standard_library} go into the -devel subpackage
# - License files go into the main package.
# - To aid debugging of cmxs files, their debuginfo is preserved by removing the executable bit.
#
# get rid of %{_rpmconfigdir}/find-debuginfo.sh
# strip kills the bytecode part of ELF binaries
#
# provide empty _find_debuginfo_dwz_opts
# the .dwz files contains identical contents, which leads to identical
# checksums, which leads to file conflicts due to identical symlinks
%%ocaml_standard_library %{ocaml_standard_library}
%if %{do_opt}
%%ocaml_preserve_bytecode \
%%define _lto_cflags %%{nil} \
%%{nil}
%%ocaml_native_compiler 1
%%_find_debuginfo_dwz_opts %%{nil}
%else
%%ocaml_preserve_bytecode \
%%undefine _build_create_debug \
%%define __arch_install_post export NO_BRP_STRIP_DEBUG=true \
%%define _lto_cflags %%{nil} \
%%{nil}
%%ocaml_native_compiler 0
%endif
# Create file list for base pkg and base-devel pkg
# Files with known extensions or names are written to 'files' or 'files.devel'
# Other unknown files are shown on stdout
%%ocaml_create_file_list \
> %%{name}.files ;\
> %%{name}.files.changes ;\
> %%{name}.files.devel ;\
> %%{name}.files.ldsoconf ;\
> %%{name}.files.license ;\
> %%{name}.files.unhandled ;\
for changes in \\\
CHANGELOG.md \\\
CHANGES \\\
CHANGES.md \\\
CHANGES.txt \\\
ChangeLog \\\
Changelog \\\
;\
do\
test -f "${changes}" && echo "%%%%doc ${changes}" >> '%%{name}.files.changes' ;\
done ;\
for license in \\\
COPYING \\\
COPYING.txt \\\
COPYRIGHT \\\
COPYRIGHT.txt \\\
Copyright \\\
LGPL \\\
LICENCE \\\
LICENSE \\\
LICENSE.md \\\
LICENSE.txt \\\
;\
do\
%if 0%{?suse_version} > 1315
license_macro='license' ;\
%else
license_macro='doc' ;\
%endif
test -f "${license}" && echo "%%%%${license_macro} ${license}" >> '%%{name}.files.license' ;\
done ;\
find %%{buildroot}%%{ocaml_standard_library} -name '*.cmxs' -exec chmod -v a-x '{}' +\
find %%{buildroot}%%{ocaml_standard_library} ! -type d | awk\\\
-v "buildroot=%%{buildroot}"\\\
-v "ocaml_standard_library=%%{ocaml_standard_library}"\\\
-v "out_files_devel=%%{name}.files.devel"\\\
-v "out_files_ldconf=%%{name}.files.ldsoconf"\\\
-v "out_files_unhandled=%%{name}.files.unhandled"\\\
-v "ocaml_ldconf=$(ls -1d %%{ocaml_standard_library}/ld.conf || : ld.conf not found)"\\\
'\
BEGIN {\
nr=0\
if (ocaml_ldconf != "") {\
do {\
r = getline < ocaml_ldconf\
if (r > 0) {\
ldconf[nr++]=$0\
}\
} while (r > 0)\
}\
}\
function _split (line) {\
file_path=substr(line, length(buildroot) + 1)\
m=match(file_path, "/[^/]+$")\
dirname=substr(file_path, 0, m - 1)\
basename=substr(file_path, m + 1)\
if (dirname == ocaml_standard_library) {\
# do not package above standard_library\
parent_dir=""\
} else {\
m=match(dirname, "/[^/]+$")\
parent_dir=substr(dirname, 0, m - 1)\
}\
}\
function files_ldconf(line) {\
_split(line)\
print file_path >> out_files_devel\
print "%%dir " dirname >> out_files_devel\
for (ldconf_dir in ldconf) {\
if (dirname == ldconf[ldconf_dir]) {\
# done with this cycle, ocaml ld.conf covers it\
next\
}\
}\
print dirname >> out_files_ldconf\
next\
}\
function files_devel(line) {\
_split(line)\
print file_path >> out_files_devel\
print "%%dir " dirname >> out_files_devel\
if (parent_dir != "") {\
print "%%dir " parent_dir >> out_files_devel\
}\
next\
}\
function files_unhandled(line) {\
_split(line)\
print file_path >> out_files_unhandled\
next\
}\
# for findlib, describing a package\
/\\/META$/{\
files_devel($0)\
}\
# stub ELF library\
/\\/[^/]+\.so$/{\
files_ldconf($0)\
}\
# stub ELF library\
/\\/[^/]+\.so.owner$/{\
files_ldconf($0)\
}\
# ELF archive with object files\
/\\/[^/]+\.a$/{\
files_devel($0)\
}\
# OCaml legacy source code annotations, produced via -annot\
/\\/[^/]+\.annot$/{\
files_devel($0)\
}\
# OCaml library file with bytecode\
/\\/[^/]+\.cma$/{\
files_devel($0)\
}\
# OCaml compiled header file\
/\\/[^/]+\.cmi$/{\
files_devel($0)\
}\
# OCaml object file with bytecode\
/\\/[^/]+\.cmo$/{\
files_devel($0)\
}\
# OCaml source code annotations, produced via -bin-annot from source files\
/\\/[^/]+\.cmt$/{\
files_devel($0)\
}\
# OCaml source code annotations, produced via -bin-annot from header files\
/\\/[^/]+\.cmti$/{\
files_devel($0)\
}\
# OCaml object file with native code\
/\\/[^/]+\.cmx$/{\
files_devel($0)\
}\
# OCaml library file with native code\
/\\/[^/]+\.cmxa$/{\
files_devel($0)\
}\
# ELF shared library with native code\
/\\/[^/]+\.cmxs$/{\
files_devel($0)\
}\
# Some helper binary\
/\\/[^/]+\.exe$/{\
files_devel($0)\
}\
# C header\
/\\/[^/]+\.h$/{\
files_devel($0)\
}\
#\
/\\/[^/]+\.js$/{\
files_devel($0)\
}\
# OCaml source code, source file\
/\\/[^/]+\.ml$/{\
files_devel($0)\
}\
# OCaml source code, header file\
/\\/[^/]+\.mli$/{\
files_devel($0)\
}\
# ELF object file\
/\\/[^/]+\.o$/{\
files_devel($0)\
}\
#\
/\\/[^/]+\.sml$/{\
files_devel($0)\
}\
# generated by dune\
/\\/dune-package$/{\
files_devel($0)\
}\
# generated by dune\
/\\/opam$/{\
files_devel($0)\
}\
# Some Coq files\
/\\/[^/]+\.v$/{\
files_devel($0)\
}\
#\
# record unknown paths\
files_unhandled($0)\
END {\
;\
}' ;\
cat '%%{name}.files.changes' >> '%%{name}.files' ;\
cat '%%{name}.files.license' >> '%%{name}.files' ;\
if test -s %%{name}.files.ldsoconf ;\
then\
ldsoconfd='/etc/ld.so.conf.d' ;\
mkdir -vp "%%{buildroot}${ldsoconfd}" ;\
tee "%%{buildroot}${ldsoconfd}/%%{name}.conf" < %%{name}.files.ldsoconf ;\
echo "%config ${ldsoconfd}/%%{name}.conf" >> %%{name}.files.devel ;\
fi ;\
for i in \\\
%%{name}.files \\\
%%{name}.files.devel \\\
%%{name}.files.ldsoconf \\\
%%{name}.files.unhandled \\\
;\
do\
sort -u $i > $$ ;\
mv $$ $i ;\
done ;\
%%{nil}
# setup.ml comes from oasis, but this is here for libs oasis depends on
#
# html goes into a separate, browsable dir
# which is also safe regarding wiping due to %%doc macro usage
%%_oasis_docdir_base %%{_datadir}/doc/ocaml
%%_oasis_docdir_dvi %%{_oasis_docdir_base}/%%{name}
%%_oasis_docdir_html %%{_oasis_docdir_base}/%%{name}
%%_oasis_docdir_pdf %%{_oasis_docdir_base}/%%{name}
%%_oasis_docdir_ps %%{_oasis_docdir_base}/%%{name}
%%oasis_docdir %%{_oasis_docdir_base}/%%{name}
#
# For now provide a convinience macro which covers also the parent dir
%%oasis_docdir_dvi %%dir %%{_oasis_docdir_base} \
%%{_oasis_docdir_dvi}
%%oasis_docdir_html %%dir %%{_oasis_docdir_base} \
%%{_oasis_docdir_html}
%%oasis_docdir_pdf %%dir %%{_oasis_docdir_base} \
%%{_oasis_docdir_pdf}
%%oasis_docdir_ps %%dir %%{_oasis_docdir_base} \
%%{_oasis_docdir_ps}
#
# various macros to unify setup/build/install
%%oasis_setup \
oasis setup
%%ocaml_oasis_configure \
ocaml setup.ml -configure \\\
--psdir %%{_oasis_docdir_ps} \\\
--pdfdir %%{_oasis_docdir_pdf} \\\
--dvidir %%{_oasis_docdir_dvi} \\\
--htmldir %%{_oasis_docdir_html} \\\
--docdir %%{oasis_docdir} \\\
--localedir %%{_datadir}/locale \\\
--datadir %%{_datadir} \\\
\\\
--bindir %%{_bindir} \\\
--mandir %%{_mandir} \\\
--destdir %%{buildroot} \\\
--datarootdir %%{_datadir} \\\
--infodir %%{_infodir} \\\
--libdir %%{_libdir} \\\
--libexecdir %%{_libexecdir} \\\
--localstatedir %%{_localstatedir} \\\
--sbindir %%{_sbindir} \\\
--prefix %%{_prefix} \\\
--sysconfdir %%{_sysconfdir} \\\
--exec-prefix %%{_prefix} \\\
--sharedstatedir %%{_sharedstatedir}
#
%%ocaml_oasis_build \
ocaml setup.ml -build
%%ocaml_oasis_doc \
ocaml setup.ml -doc
%%ocaml_oasis_install \
ocaml setup.ml -install
%%ocaml_oasis_findlib_install \
export OCAMLFIND_DESTDIR=%%{buildroot}%%{ocaml_standard_library} ; \
export OCAMLFIND_LDCONF=/dev/null ; \
mkdir -p $OCAMLFIND_DESTDIR ; \
ocaml setup.ml -install
%%ocaml_oasis_test \
ocaml setup.ml -test
#
%%ocaml_dune_setup \
%ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \
%endif
echo '%%{version}' | tee VERSION ; \
for opam in *.opam \
do\
test -f "${opam}" || continue ; \
sed -i~ '\
/^version:/d\
' "${opam}" ; \
diff -u "$_"~ "$_" || : got version ; \
done ; \
if test -f 'dune-project' ; \
then \
sed -i~ '\
/^([[:blank:]]*version[[:blank:]]\\+/d\
/^([[:blank:]]*lang[[:blank:]]\\+dune[[:blank:]]/a (version %%{version})\
' 'dune-project'; \
diff -u "$_"~ "$_" || : got version ; \
fi ; \
dune_for_release= ; \
: dune_release_pkgs \
if test -n "${dune_release_pkgs}" ; \
then \
echo "${dune_release_pkgs}" > dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
fi ; \
dune installed-libraries $OCAML_DUNE_INSTALLED_LIBRARIES_ARGS ; \
dune external-lib-deps \\\
${dune_for_release} \\\
'@install' \\\
$OCAML_DUNE_EXTERNAL_LIB_DEPS_ARGS ; \
dune external-lib-deps \\\
${dune_for_release} \\\
'@runtest' \\\
$OCAML_DUNE_EXTERNAL_LIB_DEPS_ARGS ; \
dune external-lib-deps \\\
${dune_for_release} \\\
'@install' '@runtest' \\\
$OCAML_DUNE_EXTERNAL_LIB_DEPS_ARGS \\\
| awk '/^-[[:blank:]]/{ printf "BuildRequires: ocamlfind(%%s)\\n", $2}' | sort -u ; \
%%{nil}
%%ocaml_dune_build \
if test -z "${_smp_mflags}" ;\
then \
_smp_mflags='%%{?_smp_mflags}' ;\
case "$(ocamlc --version)" in \\\
4.08*) _smp_mflags='-j1' ;;\\\
4.09*) _smp_mflags='-j1' ;;\\\
4.10*) _smp_mflags='-j1' ;;\\\
esac ;\
fi ;\
dune build \\\
--verbose \\\
${dune_for_release} \\\
${_smp_mflags} \\\
'@install' \\\
$OCAML_DUNE_BUILD_INSTALL_ARGS
%%ocaml_dune_install \
%ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \
%endif
if test -z "${_smp_mflags}" ;\
then \
_smp_mflags='%%{?_smp_mflags}' ;\
case "$(ocamlc --version)" in \\\
4.08*) _smp_mflags='-j1' ;;\\\
4.09*) _smp_mflags='-j1' ;;\\\
4.10*) _smp_mflags='-j1' ;;\\\
esac ;\
fi ;\
dune_for_release= ;\
if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
then \
read dune_release_pkgs < dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
fi ;\
dune install \\\
--verbose \\\
${dune_for_release} \\\
${_smp_mflags} \\\
--prefix=%%{_prefix} \\\
--libdir=%%{ocaml_standard_library} \\\
--destdir=%%{buildroot} \\\
${dune_release_pkgs//,/ } \\\
$OCAML_DUNE_INSTALL_ARGS ;\
rm -rfv %%{buildroot}%%{_prefix}/doc ;\
if test -d %%{buildroot}%%{_prefix}/man ; then \
mkdir -vp %%{buildroot}%%{_datadir} ; \
mv -vt %%{buildroot}%%{_datadir} %%{buildroot}%%{_prefix}/man ; \
fi ;
%%ocaml_dune_test \
%ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \
%endif
dune_for_release= ; \
if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
then \
read dune_release_pkgs < dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
fi ; \
if dune runtest \\\
--verbose \\\
${dune_for_release} \\\
$OCAML_DUNE_RUNTEST_ARGS ; \
then \
echo "dune runtest succeeded" ; \
else \
echo "dune runtest failed" ; \
if test -n "${dune_test_tolerate_fail}" ; \
then \
echo "ignored" ; \
else \
echo "aborting" ; \
exit 1 ; \
fi ; \
fi
#
#
_EOF_
%files
%{_rpmmacrodir}/*
%{_rpmconfigdir}/fileattrs
%attr(755,root,root) %{_rpmconfigdir}/*.sh
%changelog