diff --git a/ocaml-findlib.rpm.prov_req.attr.sh b/ocaml-findlib.rpm.prov_req.attr.sh index 7b7ff30..21c620b 100644 --- a/ocaml-findlib.rpm.prov_req.attr.sh +++ b/ocaml-findlib.rpm.prov_req.attr.sh @@ -33,14 +33,15 @@ do_work() { cmd="${cmd}" \ awk ' BEGIN { - dbg=1; + dbg=0; count=1; depth=0; pkg_name=ENVIRON["pkg_name"]; cmd=ENVIRON["cmd"]; if(dbg) printf "bEGIN \\"%s\\" cmd: %s\n", pkg_name, cmd > "/dev/stderr" ; - reqs[pkg_name]="" + requires[pkg_name]="" + ppx_runtime_deps[pkg_name]="" pkg_names[depth]=pkg_name } @@ -73,8 +74,8 @@ do_work() { } if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ; if (candidate != pkg_name) { - reqs[candidate] = reqs[pkg_name]; - delete reqs[pkg_name]; + requires[candidate] = requires[pkg_name]; + delete requires[pkg_name]; pkg_name = candidate; if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ; pkg_names[depth]=pkg_name @@ -86,14 +87,76 @@ do_work() { next } - /^[[:blank:]]*requires.*[[:blank:]]*=/ { + /^[[:blank:]]*requires(|\([^)]+\))[[:blank:]]*(+=|=)/ { if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ; - x = split($0, a, "\\""); + done=0 + requires_line = "" + do { + need_next_line = 1 + line = $0 + requires_line = sprintf("%s%s", requires_line, line) + l = length(requires_line) + qm = index(requires_line, "\\"") + if (l > qm) { + line = substr(requires_line, qm + 1) + qm = index(line, "\\"") + need_next_line = qm == 0 + } + + if (need_next_line) { + done = getline == 0 + } else { + done = 1 + } + } while (done == 0) + + x = split(requires_line, a, "\\""); if ( a[2] ) { if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; x = gsub("[[:blank:]]+", ",", a[2]); if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; - reqs[pkg_name] = a[2]; + if (requires[pkg_name] == "") { + requires[pkg_name] = a[2] + } else { + requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2]) + } + } + next + } + + /^[[:blank:]]*ppx_runtime_deps[[:blank:]]*(+=|=)/ { + if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ; + done=0 + ppx_runtime_deps_line = "" + do { + need_next_line = 1 + line = $0 + ppx_runtime_deps_line = sprintf("%s%s", ppx_runtime_deps_line, line) + l = length(ppx_runtime_deps_line) + qm = index(ppx_runtime_deps_line, "\\"") + if (l > qm) { + line = substr(ppx_runtime_deps_line, qm + 1) + qm = index(line, "\\"") + need_next_line = qm == 0 + } + + if (need_next_line) { + done = getline == 0 + } else { + done = 1 + } + } while (done == 0) + + x = split(ppx_runtime_deps_line, a, "\\""); + if ( a[2] ) { + if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; + x = gsub("[[:blank:]]+", ",", a[2]); + if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; + if (ppx_runtime_deps[pkg_name] == "") { + ppx_runtime_deps[pkg_name] = a[2] + } else { + requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2]) + } } next } @@ -106,7 +169,7 @@ do_work() { if ( a[2] ) { if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; pkg_name = pkg_name"."a[2]; - reqs[pkg_name]="" + requires[pkg_name]="" pkg_names[depth]=pkg_name if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ; } @@ -124,10 +187,15 @@ do_work() { END { if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ; - for (req in reqs) { + for (req in requires) { if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr"; # format: provides:requires - printf "%s:%s\n", req, reqs[req]; + printf "%s:%s\n", req, requires[req]; + } + for (req in ppx_runtime_deps) { + if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr"; + # format: provides:requires + printf "%s:%s\n", req, ppx_runtime_deps[req]; } if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ; } @@ -158,3 +226,4 @@ do *) ;; esac done +# vim: tw=666 ts=2 shiftwidth=2 et diff --git a/ocaml-ocaml.rpm.prov_req.attr.sh b/ocaml-ocaml.rpm.prov_req.attr.sh new file mode 100644 index 0000000..e152c76 --- /dev/null +++ b/ocaml-ocaml.rpm.prov_req.attr.sh @@ -0,0 +1,243 @@ +#!/bin/bash +# This is a helper for rpm which collects 'Provides' and 'Requires' information from OCaml files. +# It reads a list of filenames from STDIN. +# It expects as argument either '--provides|-P' or '--requires|-R'. +# Additional optional arguments are: +# -f "ocamlobjinfo command" +# -c # ignored, recognized just for compat reasons +# -i NAME # omit the Requires/Provides for this bytecode unit name +# -x NAME # omit the Requires/Provides for this native unit name +# +# OCaml object files contain either bytecode or native code. +# Each bytecode variant provides a certain interface, which is represented by a hash. +# Each native variant provides a certain interface and a certain implementation, which are represented by hashes. +# Each variant may also require a certain interface and/or implementation provided by other files. +# The details for each file can be inspected with 'ocamlobjinfo'. +# +# Each file contains at least one module. +# Information about each module follows after a line starting with "Name:" or "Unit name:": +# +# cma/cmi/cmo (bytecode): +# Unit name: NAME +# Interfaces imported: +# HASH NAME +# HASH NAME_FROM_OTHER_MODULE +# +# cmx/cmxa/cmxs (native): +# Name: NAME +# CRC of implementation: HASH +# Interfaces imported: +# HASH NAME +# HASH NAME_FROM_OTHER_MODULE +# Implementations imported: +# HASH NAME_FROM_OTHER_MODULE +# +# The hash may contain just '-', in which case it is ignored. +# +# Output: +# ocaml(NAME) = HASH # for interfaces (bytecode and native) +# ocamlx(NAME) = HASH # for implementations (native) + +set -e +# +OCAMLOBJINFO=ocamlobjinfo +rpm_prefix_interface='ocaml' +rpm_prefix_implementation='ocamlx' +# +parse() { + local filename="$1" + + ${OCAMLOBJINFO} "${filename}" | awk ' + BEGIN { + debug=0 + mode=ENVIRON["mode"] + RPM_BUILD_ROOT=ENVIRON["RPM_BUILD_ROOT"] + rpm_prefix_interface=ENVIRON["rpm_prefix_interface"] + rpm_prefix_implementation=ENVIRON["rpm_prefix_implementation"] + state="find" + unit="" + + split(ENVIRON["ignore_implementation"], ignore_implementation_a) + for (i in ignore_implementation_a) { + val=ignore_implementation_a[i] + if (debug) + printf "INFO: ignore_implementation %s\n", val > "/dev/stderr" + ignore_implementation[val]=1 + } + split(ENVIRON["ignore_interface"], ignore_interface_a) + for (i in ignore_interface_a) { + val=ignore_interface_a[i] + if (debug) + printf "INFO: ignore_interface %s\n", val > "/dev/stderr" + ignore_interface[val]=1 + } + } + + /^File / { + if (RPM_BUILD_ROOT != "" ) { + file=substr($2,length(RPM_BUILD_ROOT)+1) + } else { + file=$2 + } + state="file" + next + } + /^Unit name:/ { + unit=$3 + state="cma" + next + } + /^Name:/ { + unit=$2 + state="cmx" + next + } + + /^CRC of implementation:/ { + if (state == "cmx") { + if (ignore_implementation[unit] != "") { + if (ignore_implementation[unit] != "seen") { + printf "INFO: ignoring Provides %s(%s)=%s from %s\n", rpm_prefix_implementation, unit, $4, file > "/dev/stderr" + ignore_implementation[unit]="seen" + } + } else { + implementation_provides[unit]=$4 + } + } else { + printf "WARN: state %s, expected cmx, got %s\n", state, $0 > "/dev/stderr" + } + state="crc" + next + } + + /^Interfaces imported:/ { + state="interface" + next + } + + /^Implementations imported:/ { + state="implementation" + next + } + + /^\t/ { + if (state == "interface" && NF > 1 && match($1, "^-") == 0) { + if (unit == $2) { + if (ignore_interface[unit] != "") { + if (ignore_interface[unit] != "seen") { + printf "INFO: ignoring Provides %s(%s)=%s from %s\n", rpm_prefix_interface, unit, $1, file > "/dev/stderr" + ignore_interface[unit]="seen" + } + } else { + interface_provides[unit]=$1 + } + } else { + if (ignore_interface[$2] != "") { + if (ignore_interface[$2] != "seen") { + printf "INFO: ignoring Requires %s(%s)=%s from %s\n", rpm_prefix_interface, $2, $1, file > "/dev/stderr" + ignore_interface[$2]="seen" + } + } else { + interface_requires[$2]=$1 + } + } + next + } else if (state == "implementation" && NF > 1 && match($1, "^-") == 0) { + if (unit == $2) { + if (ignore_implementation[unit] != "") { + if (ignore_implementation[unit] != "seen") { + printf "INFO: ignoring Provides %s(%s)=%s from %s\n", rpm_prefix_implementation, unit, $1, file > "/dev/stderr" + ignore_implementation[unit]="seen" + } + } else { + implementation_provides[unit]=$1 + } + } else { + if (ignore_implementation[$2] != "") { + if (ignore_implementation[$2] != "seen") { + printf "INFO: ignoring Requires %s(%s)=%s from %s\n", rpm_prefix_implementation, $2, $1, file > "/dev/stderr" + ignore_implementation[$2]="seen" + } + } else { + implementation_requires[$2]=$1 + } + } + next + } else { + next + } + } + /^.*/ { + state="find" + } + + END { + if (mode == "provides") { + for (i in interface_provides) { + printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_provides[i] + } + for (i in implementation_provides) { + printf "%s(%s) = %s\n", rpm_prefix_implementation, i, implementation_provides[i] + } + } + if (mode == "requires") { + for (i in interface_requires) { + printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_requires[i] + } + for (i in implementation_requires) { + printf "%s(%s) = %s\n", rpm_prefix_implementation, i, implementation_requires[i] + } + } + } + ' +} +# +# +usage() { + echo >&2 "Usage: ${0##*/} -provides|-requires [-f 'ocamlobjinfo cmd']" +} +# +mode= +ignore_implementation_a=() +ignore_interface_a=() +while test "$#" -gt 0 +do + : "${1}" "${2}" + case "${1}" in + -P|--provides) mode='provides' ;; + -R|--requires) mode='requires' ;; + -i) ignore_interface_a+=("$2") ; shift ;; + -x) ignore_implementation_a+=("$2") ; shift ;; + -f) OCAMLOBJINFO="$2"; shift ;; + -h|--help) usage ; exit 0 ;; + -c) ;; # ignored + --) break ;; + *) usage ; exit 1 ;; + esac + shift +done +if test -z "${mode}" +then + usage + exit 1 +fi +# +export rpm_prefix_interface +export rpm_prefix_implementation +export mode +export ignore_implementation="${ignore_implementation_a[@]}" +export ignore_interface="${ignore_interface_a[@]}" +# +while read filename +do + case "${filename}" in + *.cma) parse "${filename}" ;; + *.cmi) parse "${filename}" ;; + *.cmo) parse "${filename}" ;; + *.cmx) parse "${filename}" ;; + *.cmxa) parse "${filename}" ;; + *.cmxs) parse "${filename}" ;; + *) continue ;; + esac +done +# vim: tw=666 ts=2 shiftwidth=2 et diff --git a/ocaml-rpm-macros.changes b/ocaml-rpm-macros.changes index 9cc5ab8..d2ff1fd 100644 --- a/ocaml-rpm-macros.changes +++ b/ocaml-rpm-macros.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Thu Feb 20 20:20:20 UTC 2020 - ohering@suse.de + +- Add ocaml-ocaml.rpm.prov_req.attr.sh + New script for rpm Provides/Requires, replacement for rpm + built-in ocaml(NAME)=hash, which covers bytecode and interfaces + Now it covers also native code via ocamlx(NAME)=HASH (bsc#1154874) +- Update the filelist generator + Use awk to match directories in ocamls built-in ld.conf + C stublibs in default locations do not need a ld.so.conf entry + Remaining ld.so.conf files for stublibs go to the devel package +- Disable debug in ocamlfind() Provides/Requires generator + Update META parser to handle multiline statements and ppx +- Provide a ocaml_standard_library macro +- Explicitly preserve debuginfo in .cmxs, already enforced by dune +- Install also COPYRIGHT.txt as license, needed for some JaneStreet pkgs + ------------------------------------------------------------------- Mon Nov 25 12:34:56 UTC 2019 - ohering@suse.de diff --git a/ocaml-rpm-macros.spec b/ocaml-rpm-macros.spec index e0b8d1e..4c8d3f1 100644 --- a/ocaml-rpm-macros.spec +++ b/ocaml-rpm-macros.spec @@ -16,14 +16,16 @@ # Name: ocaml-rpm-macros -Version: 20191101 +Version: 20200220 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: @@ -60,13 +62,25 @@ in ocaml spec files. %build %install +# map ocamlobjinfo output to rpm Provides/Requires +tag="ocaml" +mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs +tee %{buildroot}%{_rpmconfigdir}/fileattrs/z${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)$ +_EOF_ +# +tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE0} + # map findlib names to rpm Provides/Requires tag="ocamlfind" 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 ^%%{_libdir}/ocaml/.*/META$|^%%{_libdir}/ocaml/META$ +%__${tag}_path ^%{ocaml_standard_library}/.*/META$|^%{ocaml_standard_library}/META$ _EOF_ # tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1} @@ -74,12 +88,23 @@ 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} \ @@ -108,12 +133,13 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_' COPYING \\\ COPYING.txt \\\ COPYRIGHT \\\ + COPYRIGHT.txt \\\ Copyright \\\ + LGPL \\\ LICENCE \\\ LICENSE \\\ LICENSE.md \\\ LICENSE.txt \\\ - LGPL \\\ ;\ do\ %if 0%{?suse_version} > 1315 @@ -123,80 +149,168 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_' %endif test -f "${license}" && echo "%%%%${license_macro} ${license}" >> '%%{name}.files.license' ;\ done ;\ - find %%{buildroot}$(ocamlc -where) | sed -ne '\ - s@^%%{buildroot}@@\ - #\ + 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$/{ b files_devel }\ + /\\/META$/{\ + files_devel($0)\ + }\ # stub ELF library\ - /\\/[^/]\\+\\.so$/{ b files_ldsoconf }\ + /\\/[^/]+\.so$/{\ + files_ldconf($0)\ + }\ # stub ELF library\ - /\\/[^/]\\+\\.so.owner$/{ b files_ldsoconf }\ + /\\/[^/]+\.so.owner$/{\ + files_ldconf($0)\ + }\ # ELF archive with object files\ - /\\/[^/]\\+\\.a$/{ b files_devel }\ + /\\/[^/]+\.a$/{\ + files_devel($0)\ + }\ # OCaml legacy source code annotations, produced via -annot\ - /\\/[^/]\\+\\.annot$/{ b files_devel }\ + /\\/[^/]+\.annot$/{\ + files_devel($0)\ + }\ # OCaml library file with bytecode\ - /\\/[^/]\\+\\.cma$/{ b files_devel }\ + /\\/[^/]+\.cma$/{\ + files_devel($0)\ + }\ # OCaml compiled header file\ - /\\/[^/]\\+\\.cmi$/{ b files_devel }\ + /\\/[^/]+\.cmi$/{\ + files_devel($0)\ + }\ # OCaml object file with bytecode\ - /\\/[^/]\\+\\.cmo$/{ b files_devel }\ + /\\/[^/]+\.cmo$/{\ + files_devel($0)\ + }\ # OCaml source code annotations, produced via -bin-annot from source files\ - /\\/[^/]\\+\\.cmt$/{ b files_devel }\ + /\\/[^/]+\.cmt$/{\ + files_devel($0)\ + }\ # OCaml source code annotations, produced via -bin-annot from header files\ - /\\/[^/]\\+\\.cmti$/{ b files_devel }\ + /\\/[^/]+\.cmti$/{\ + files_devel($0)\ + }\ # OCaml object file with native code\ - /\\/[^/]\\+\\.cmx$/{ b files_devel }\ + /\\/[^/]+\.cmx$/{\ + files_devel($0)\ + }\ # OCaml library file with native code\ - /\\/[^/]\\+\\.cmxa$/{ b files_devel }\ + /\\/[^/]+\.cmxa$/{\ + files_devel($0)\ + }\ # ELF shared library with native code\ - /\\/[^/]\\+\\.cmxs$/{ b files_devel }\ + /\\/[^/]+\.cmxs$/{\ + files_devel($0)\ + }\ # Some helper binary\ - /\\/[^/]\\+\\.exe$/{ b files_devel }\ + /\\/[^/]+\.exe$/{\ + files_devel($0)\ + }\ # C header\ - /\\/[^/]\\+\\.h$/{ b files_devel }\ + /\\/[^/]+\.h$/{\ + files_devel($0)\ + }\ #\ - /\\/[^/]\\+\\.js$/{ b files_devel }\ + /\\/[^/]+\.js$/{\ + files_devel($0)\ + }\ # OCaml source code, source file\ - /\\/[^/]\\+\\.ml$/{ b files_devel }\ + /\\/[^/]+\.ml$/{\ + files_devel($0)\ + }\ # OCaml source code, header file\ - /\\/[^/]\\+\\.mli$/{ b files_devel }\ + /\\/[^/]+\.mli$/{\ + files_devel($0)\ + }\ # ELF object file\ - /\\/[^/]\\+\\.o$/{ b files_devel }\ + /\\/[^/]+\.o$/{\ + files_devel($0)\ + }\ #\ - /\\/[^/]\\+\\.sml$/{ b files_devel }\ - #\ - /\\/dune-package$/{ b files_devel }\ - #\ - /\\/opam$/{ b files_devel }\ + /\\/[^/]+\.sml$/{\ + files_devel($0)\ + }\ + # generated by dune\ + /\\/dune-package$/{\ + files_devel($0)\ + }\ + # generated by dune\ + /\\/opam$/{\ + files_devel($0)\ + }\ #\ # record unknown paths\ - w %%{name}.files.unhandled\ - d\ - #\ - : files_devel\ - # full path for file\ - w %%{name}.files.devel\ - # tag + dirname\ - s@\\/[^/]\\+$@@\ - : tag_dirname\ - s@^@%%dir @\ - w %%{name}.files.devel\ - # parent directory\ - s@\\/[^/]\\+$@@\ - w %%{name}.files.devel\ - d\ - #\ - : files_ldsoconf\ - # full path for file\ - w %%{name}.files.devel\ - # dirname for ld.so.conf\ - s@\\/[^/]\\+$@@\ - w %%{name}.files.ldsoconf\ - b tag_dirname\ - ' ;\ - cat '%%{name}.files.license' >> '%%{name}.files' ; \ + files_unhandled($0)\ + END {\ + ;\ + }' ;\ + 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 \\\ @@ -207,19 +321,6 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_' sort -u $i > $$ ;\ mv $$ $i ;\ done ;\ - 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 ;\ - fi ;\ - head -n 1234 \\\ - %%{name}.files \\\ - %%{name}.files.devel \\\ - %%{name}.files.ldsoconf \\\ - %%{name}.files.unhandled \\\ - ;\ %%{nil} # setup.ml comes from oasis, but this is here for libs oasis depends on @@ -277,7 +378,7 @@ ocaml setup.ml -configure \\\ %%ocaml_oasis_install \ ocaml setup.ml -install %%ocaml_oasis_findlib_install \ - export OCAMLFIND_DESTDIR=%%{buildroot}`ocamlc -where` ; \ + export OCAMLFIND_DESTDIR=%%{buildroot}%%{ocaml_standard_library} ; \ export OCAMLFIND_LDCONF=/dev/null ; \ mkdir -p $OCAMLFIND_DESTDIR ; \ ocaml setup.ml -install @@ -322,22 +423,22 @@ ocaml setup.ml -configure \\\ %ifarch ppc64 ppc64le ulimit -s $((1024 * 64)) ; \ %endif - dune_for_release= ; \ + 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 ; \ + fi ;\ dune install \\\ --verbose \\\ ${dune_for_release} \\\ %%{?_smp_mflags} \\\ --prefix=%%{_prefix} \\\ - --libdir=$(ocamlc -where) \\\ + --libdir=%%{ocaml_standard_library} \\\ --destdir=%%{buildroot} \\\ ${dune_release_pkgs//,/ } \\\ - $OCAML_DUNE_INSTALL_ARGS ; \ - rm -rfv %%{buildroot}%%{_prefix}/doc ; \ + $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 ; \