Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / scripts / mono-find-requires.in
index a721f23997f1a8e3258df5ea067da8ad8e5fc64d..5e0ef2f1cfd35e650d84d380c553d3d108a48dc0 100644 (file)
@@ -4,30 +4,55 @@
 #
 # Authors:
 #       Ben Maurer (bmaurer@ximian.com)
+#       Wade Berrier (wberrier@novell.com)
 #
-# (C) 2005 Novell (http://www.novell.com)
+# (C) 2008 Novell (http://www.novell.com)
 #
 
+if [ -n "$DISABLE_MONO_RPM_AUTO_DEPS" ]; then exit 0; fi
+
 IFS=$'\n'
 filelist=($(grep -Ev '/usr/doc/|/usr/share/doc/'))
 monolist=($(printf "%s\n" "${filelist[@]}" | egrep "\\.(exe|dll)\$"))
 
-a=`which "$0"`
-d=`dirname "$a"`
+# parse .config files to find which native libraries to depend on 
+#  (target attribute must have double quotes for this to work, ie: target="file" )
+# Add /etc/mono/config ?
+configlist=($(printf "%s\n" "${filelist[@]}" | egrep "\\.config\$"))
 
 # Set the prefix, unless it is overriden (used when building mono rpms)
-: ${prefix=$d/..}
+: ${prefix=@prefix@}
+
+# Can override .config scanning if specified
+: ${IGNORE_CONFIG_SCAN=0}
 
-exec_prefix=$d/..
 libdir=$prefix/@reloc_libdir@
-bindir=$d
+bindir=$prefix/bin
+
+# Bail out if monodis or libmono is missing
+if [ ! -x $bindir/monodis ] || [ ! -f $libdir/libmono-2.0.so.1 ] ; then
+       echo "monodis missing or unusable, exiting..." 1>&2
+       exit 1
+fi
 
-[ -x $bindir/monodis ] || exit 0;
-[ -f $libdir/libmono.so ] || exit 0;
+# special case for 64bit archs
+if test "x@reloc_libdir@" = "xlib64" ; then
+        libext="()(64bit)"
+else
+       # (note, this works on ppc64 since we only have 32bit mono)
+        libext=""
+fi
 
+# Exceptions:
+case `uname -m` in
+       # ia64 doesn't use lib64 for 'libdir' (sles 9 rpm used to provide both... no longer)
+       ia64)   libext="()(64bit)" ;;
+esac
 
-# set LD_LIBRARY_PATH to ensure that libmono.so is found
+# set LD_LIBRARY_PATH to ensure that libmono is found
 export LD_LIBRARY_PATH=$libdir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+# and set MONO_PATH to ensure that mscorlib.dll can be found
+export MONO_PATH=$prefix/lib/mono/4.5
 
 REQUIRES=$(
        for i in "${monolist[@]}"; do
@@ -38,18 +63,98 @@ REQUIRES=$(
                                sub(/Version=/, "", $2);
                                VERSION=$2
                        }
-       
+
                        (START==1) && /^\tName=/ {
                                sub(/Name=/, "", $1);
                                LIBNAME=$1
-       
-                               print "mono(" LIBNAME ") = " VERSION
+                               # Allow rpm deps to be resolved for 1.0 profile version
+                               if (VERSION=="1.0.3300.0")
+                                       OP=">="
+                               else
+                                       OP="="
+                               print "mono(" LIBNAME ") " OP " " VERSION
                                START=0
                        }
                    ') 2> /dev/null
        done
 )
 
+if [ $IGNORE_CONFIG_SCAN -eq 0 ] ; then
+
+rpm_config_REQUIRES=$(
+       # Parse the xml .config files to see what native binaries we call into
+       # TODO: also check monodis --moduleref
+       for i in "${configlist[@]}"; do
+               awk 'match($_, /<dllmap .*target=.*/) {
+                       ignore=0
+                       req=""
+                       split($_, toks, "\"")
+                       toks_size=0
+                        for(tok in toks) { toks_size++ }
+                       for(i=1; i <= toks_size; i++) {
+                               if(toks[i] ~ /target=/) {
+                                       req=toks[i+1]
+                               }
+                               if(toks[i] ~ /os=/) {
+                                       negate=0
+                                       found=0
+
+                                       attr=toks[i+1]
+                                       if(attr ~ /^!/) {
+                                               attr=substr(attr, 2, length(attr)-1)
+                                               negate=1
+                                       }
+
+                                       split(attr, os_targets, ",")
+                                       os_targets_size=0
+                                        for(os_target in os_targets) { os_targets_size++ }
+                                       for(j=1; j <= os_targets_size; j++) {
+                                               if(os_targets[j] == "linux") {
+                                                       found=1
+                                               }
+                                       }
+
+                                       if(negate) {
+                                               found=!found
+                                       }
+                                       if (!found) {
+                                               ignore=1
+                                       } 
+                               }
+                       }
+                       if(!ignore) {
+                               print req"'$libext'"
+                       }
+               } ' $i 2>/dev/null
+       done
+)
+
+# Resolve provides to packages, warning on missing to stderr
+config_REQUIRES=$(
+       first=1 # avoid an empty line if no .config reqs are found
+       for i in ${rpm_config_REQUIRES[@]} ; do
+               out=$(rpm -q --whatprovides --queryformat "%{NAME}\n" $i)
+               if [ $? -eq 0 ] ; then
+                       if [ $first -eq 1 ] ; then
+                              echo ""
+                              first=0
+                       fi
+                       echo $out
+               else
+                       # echo to stderr
+                       echo "mono-find-requires: Warning, could not find package that provides: $i" >&2
+               fi
+       done
+)
+
+fi
+
+# Note about above:
+#  Use to do: system("rpm -q --whatprovides --queryformat \"%{NAME}\n\" ""\""req"'$libext'""\"")
+#  rpmlint prefers to have lib names instead of package names.  There was a reason I was using package names but it slips me now...
+#  Ah... now I remember... it's for noarch packs.  The noarch packages can be built on either 32 or 64 bit... so we have to depend
+#   on the package name instead.
+
 PROVIDES=$(
        for i in "${monolist[@]}"; do
                ($bindir/monodis --assembly $i | awk '
@@ -68,9 +173,10 @@ PROVIDES=$(
 # in PROVIDES. While RPM functions correctly when such deps exist,
 # they make the metadata a bit bloated.
 #
+# TODO: make this use the mono-find-provides script, to share code
 
 # Filter out dups from both lists
-REQUIRES=$(echo "$REQUIRES" | sort | uniq)
+REQUIRES=$(echo "$REQUIRES $config_REQUIRES"  | sort | uniq)
 PROVIDES=$(echo "$PROVIDES" | sort | uniq)
 
 #