changeset 3665:4e16cc19161b octave-forge

handle dependencies in installers (main and pkg packages)
author goffioul
date Wed, 18 Jul 2007 12:40:45 +0000
parents 41f860e3d879
children 7edd4e6b07b9
files admin/Windows/msvc/.cvsignore admin/Windows/msvc/octave.nsi.in admin/Windows/msvc/octave_package.nsi.in admin/Windows/msvc/run_compilation.sh
diffstat 4 files changed, 239 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/admin/Windows/msvc/.cvsignore	Tue Jul 17 17:14:51 2007 +0000
+++ b/admin/Windows/msvc/.cvsignore	Wed Jul 18 12:40:45 2007 +0000
@@ -1,6 +1,7 @@
 makeall.sh
 octave_forge.nsi
 octave_forge_desc.nsi
+octave_forge_deps.nsi
 octave_main.nsi
 octave_pkg_*.nsi
 octave-*-setup.exe
--- a/admin/Windows/msvc/octave.nsi.in	Tue Jul 17 17:14:51 2007 +0000
+++ b/admin/Windows/msvc/octave.nsi.in	Wed Jul 18 12:40:45 2007 +0000
@@ -536,11 +536,11 @@
   Pop $0
   StrCmp "" "$0" nojvm jvm
 jvm:
-  !insertmacro SetSectionFlag ${SEC_JAVA} ${SF_SELECTED}
+  !insertmacro SetSectionFlag ${SEC_java} ${SF_SELECTED}
   !insertmacro SetSectionFlag ${SEC_JHANDLES} ${SF_SELECTED}
   Goto endjvm
 nojvm:
-  !insertmacro ClearSectionFlag ${SEC_JAVA} ${SF_SELECTED}
+  !insertmacro ClearSectionFlag ${SEC_java} ${SF_SELECTED}
   !insertmacro ClearSectionFlag ${SEC_JHANDLES} ${SF_SELECTED}
 endjvm:
 !ifdef USE_MSYS
@@ -827,11 +827,39 @@
   Pop $0
 FunctionEnd
 
+Var DEP_FLAG
+
+!macro CheckDependency pack1 pack2
+  Push ${pack1}
+  Push ${pack2}
+  Call CheckDependency
+!macroend
+
+Function CheckDependency
+  Exch $1
+  Exch
+  Exch $0
+  !insertmacro SectionFlagIsSet $0 ${SF_SELECTED} 0 done
+  !insertmacro SectionFlagIsSet $1 ${SF_SELECTED} done ""
+  StrCpy $DEP_FLAG 1
+  !insertmacro SetSectionFlag $1 ${SF_SELECTED}
+done:
+  Pop $0
+  Pop $1
+FunctionEnd
+
 Function componentsLeave
+  StrCpy $DEP_FLAG 0
+!ifdef USE_OCTAVE_FORGE
+  !insertmacro CheckDependency ${SEC_JHANDLES} ${SEC_java}
+  !include "octave_forge_deps.nsi"
+!endif
+  StrCmp $DEP_FLAG 0 +2
+  MessageBox MB_OK|MB_ICONINFORMATION "Some components were automatically selected to satisfy dependencies"
 !ifdef JHANDLES_VERSION
   !insertmacro SectionFlagIsSet ${SEC_JHANDLES} ${SF_SELECTED} check_jvm ""
 !endif
-  !insertmacro SectionFlagIsSet ${SEC_JAVA} ${SF_SELECTED} check_jvm done
+  !insertmacro SectionFlagIsSet ${SEC_java} ${SF_SELECTED} check_jvm done
 check_jvm:
   Call DetectJVM
   Pop $0
--- a/admin/Windows/msvc/octave_package.nsi.in	Tue Jul 17 17:14:51 2007 +0000
+++ b/admin/Windows/msvc/octave_package.nsi.in	Wed Jul 18 12:40:45 2007 +0000
@@ -24,6 +24,7 @@
 !include "Sections.nsh"
 !include "WordFunc.nsh"
 !insertmacro WordReplace
+!insertmacro WordFind
 
 ; MUI Settings
 !define MUI_ABORTWARNING
@@ -40,6 +41,7 @@
 ; Instfiles page
 !insertmacro MUI_PAGE_INSTFILES
 ; Finish page
+!define MUI_FINISHPAGE_TEXT "$(MUI_TEXT_FINISH_INFO_TEXT)\r\n\r\nThis package does not provide an uninstaller. To uninstall ${PRODUCT_NAME}-${PRODUCT_VERSION}, use the regular Octave package manager with the 'uninstall' command (see 'help pkg' for more information). It will also be removed if you uninstall Octave."
 !insertmacro MUI_PAGE_FINISH
 
 ; Language files
@@ -56,6 +58,7 @@
 XPStyle on
 
 Var IS_WIN2K
+Var OCTAVE_EXEC
 
 Section "${PACKAGE_LONG_NAME}" SEC_@PACKAGE_NAME@
   SetOverwrite try
@@ -63,7 +66,7 @@
   SetOutPath "$INSTDIR\${PACKAGE_NAME}-${PACKAGE_VERSION}"
   File /r "${OCTAVE_ROOT}\share\octave\packages\${PACKAGE_NAME}-${PACKAGE_VERSION}\*"
   
-  ExecWait '"$INSTDIR\..\..\..\bin\octave.exe" -qf --eval "pkg rebuild ${PACKAGE_NAME}"'
+  ExecWait '"$OCTAVE_EXEC" -qf --eval "pkg rebuild ${PACKAGE_NAME}"'
 SectionEnd
 
 ; Section descriptions
@@ -71,18 +74,44 @@
   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_@PACKAGE_NAME@} "${PACKAGE_INFO}"
 !insertmacro MUI_FUNCTION_DESCRIPTION_END
 
+!macro MissingComponent compname
+  MessageBox MB_ICONSTOP|MB_OK "${PRODUCT_NAME}-${PRODUCT_VERSION} cannot be installed on this computer, because some required components$\r$\nare not present. Install the missing components and run this installer again.$\r$\n$\r$\nMissing components:  ${compname}"
+!macroend
+
+!macro CheckDependency packname packver op
+  Push "${packname}"
+  Push "${packver}"
+  Push "${op}"
+  Call CheckDependency
+  Exch $0
+  StrCmp $0 "0" 0 +6
+  StrCmp ${packver} "" 0 +3
+  !insertmacro MissingComponent "${packname}"
+  Goto +2
+  !insertmacro MissingComponent "${packname} (${op} ${packver})"
+  Abort
+  Pop $0
+!macroend
+
 Function .onInit
   ReadRegStr $INSTDIR ${PRODUCT_ROOT_KEY} "${PRODUCT_DIR_REGKEY}" Packages
   StrCmp $INSTDIR "" 0 octave_present
-  MessageBox MB_ICONSTOP|MB_OK "Octave ${OCTAVE_VERSION} not found on this system.$\r$\nThis package cannot be installed"
+  !insertmacro MissingComponent "Octave ${OCTAVE_VERSION}"
   Abort
 octave_present:
+  ReadRegStr $OCTAVE_EXEC ${PRODUCT_ROOT_KEY} "${PRODUCT_DIR_REGKEY}" ""
   Call DetectWinVer
   Call DetectAdmin
   Pop $0
   StrCmp $0 1 0 endadmin
   SetShellVarContext all
 endadmin:
+  @PACKAGE_DEPENDENCY@
+  IfFileExists "$INSTDIR\${PACKAGE_NAME}-*" 0 endinit
+  MessageBox MB_YESNOCANCEL|MB_ICONQUESTION "${PRODUCT_NAME} is already installed on this computer. The existing version must be uninstalled$\r$\nbefore running this installer. Do you want to remove the existing version?" IDYES +2 IDNO endinit
+  Abort
+  ExecWait '"$OCTAVE_EXEC" -qf --eval "pkg uninstall ${PACKAGE_NAME}"'
+endinit:
 FunctionEnd
 
 Function DetectAdmin
@@ -170,3 +199,81 @@
   Pop $1
   Pop $0
 FunctionEnd
+
+Function CompareVersion
+  Exch $1
+  Exch
+  Exch $0
+  Push $2
+  Push $3
+  ${WordFind} "$0" "." "+1" $2
+  ${WordFind} "$1" "." "+1" $3
+  IntCmp $2 $3 0 result_1 result1
+  ${WordFind} "$0" "." "+2" $2
+  ${WordFind} "$1" "." "+2" $3
+  IntCmp $2 $3 0 result_1 result1
+  ${WordFind} "$0" "." "+3" $2
+  ${WordFind} "$1" "." "+3" $3
+  IntCmp $2 $3 result0 result_1 result1
+result_1:
+  StrCpy $1 -1
+  Goto compare_end
+result0:
+  StrCpy $1 0
+  Goto compare_end
+result1:
+  StrCpy $1 1
+compare_end:
+  Pop $3
+  Pop $2
+  Pop $0
+  Exch $1
+FunctionEnd
+
+Function CheckDependency
+  Exch $R0
+  Exch
+  Exch $1
+  Exch
+  Exch 2
+  Exch $0
+  Push $2
+  Push $3
+  FindFirst $2 $3 "$INSTDIR\$0-*"
+  StrCmp $3 "" dep_not_ok
+  StrCmp $1 "" dep_ok
+  ${WordFind} "$3" "-" "-1" $3
+  Push $3
+  Push $1
+  Call CompareVersion
+  Pop $3
+  StrCmp $R0 "<" cmp_lt
+  StrCmp $R0 "<=" cmp_le
+  StrCmp $R0 ">" cmp_gt
+  StrCmp $R0 ">=" cmp_ge
+  StrCmp $R0 "==" cmp_eq
+  Goto dep_not_ok
+cmp_lt:
+  IntCmp $3 0 dep_not_ok dep_ok dep_not_ok
+cmp_le:
+  IntCmp $3 0 dep_ok dep_ok dep_not_ok
+cmp_gt:
+  IntCmp $3 0 dep_not_ok dep_not_ok dep_ok
+cmp_ge:
+  IntCmp $3 0 dep_ok dep_not_ok dep_ok
+cmp_eq:
+  IntCmp $3 0 dep_ok dep_not_ok dep_not_ok
+dep_not_ok:
+  StrCpy $1 0
+  Goto done
+dep_ok:
+  StrCpy $1 1
+done:
+  FindClose $2
+  Pop $3
+  Pop $2
+  Pop $0
+  Exch $1
+  Exch
+  Pop $R0
+FunctionEnd
--- a/admin/Windows/msvc/run_compilation.sh	Tue Jul 17 17:14:51 2007 +0000
+++ b/admin/Windows/msvc/run_compilation.sh	Wed Jul 18 12:40:45 2007 +0000
@@ -1552,7 +1552,7 @@
 # NSI package generation #
 ##########################
 
-isolated_packages="fpl bim msh secs1d secs2d"
+isolated_packages="fpl msh bim secs1d secs2d"
 
 function get_nsi_additional_files()
 {
@@ -1596,11 +1596,23 @@
   esac
 }
 
+function get_nsi_dependencies()
+{
+  packname=$1
+  descfile="$2"
+  sed -n -e 's/ *$//' \
+         -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \
+         -e 's/^depends: //p' "$descfile" | \
+    awk -F ', ' '{c=split($0, s); for(n=1; n<=c; ++n) printf("%s\n", s[n]) }' | \
+      sed -n -e 's/^octave.*$//' \
+             -e 's/\([a-zA-Z0-9_]\+\) *\(( *\([<>]=\?\) *\([0-9]\+\.[0-9]\+\.[0-9]\+\) *) *\)\?/  !insertmacro CheckDependency "\1" "\4" "\3"/p'
+}
+
 function create_nsi_entries()
 {
   pkgs=`for d in $1; do echo $d; done | sort - | sed -e ':a;N;$!ba;s/\n/\ /g'`
   flag=$2
-  dodesc=$3
+  op=$3
   for packname in $pkgs; do
     if test "$packname" = "jhandles"; then
       continue
@@ -1610,26 +1622,39 @@
     fi
     found=`find "$octave_prefix/share/octave/packages" -type d -a -name "$packname-*" -maxdepth 1`
     if test ! -z "$found"; then
-      packdesc=`grep -e '^Name:' "$found/packinfo/DESCRIPTION" | sed -e 's/^Name *: *//'`
-      packdesc_low=`echo $packdesc | sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
-      packver=`grep -e '^Version:' "$found/packinfo/DESCRIPTION" | sed -e 's/^Version *: *//'`
-      packinstdir=$packdesc_low-$packver
-      if test -z "$dodesc"; then
-        if test "$packdesc_low" = "windows" -o "$packdesc_low" = "java" -o "$packdesc_low" = "arpack"; then
-          flag_=
-        else
-          flag_=$flag
-        fi
-        echo "Section $flag_ \"$packdesc\" SEC_$packname"
-        echo "  SetOverwrite try"
-        get_nsi_additional_files $packname
-        echo "  SetOutPath \"\$INSTDIR\\share\\octave\\packages\\$packinstdir\""
-        echo "  File /r \"\${OCTAVE_ROOT}\\share\\octave\\packages\\$packinstdir\\*\""
-        echo "SectionEnd"
-      else
-        packinfo=`sed -e '/^ /{H;$!d;}' -e 'x;/^Description: /!d;' "$found/packinfo/DESCRIPTION" | sed -e ':a;N;$!ba;s/\n */\ /g' | sed -e 's/^Description: //'`
-        echo "  !insertmacro MUI_DESCRIPTION_TEXT \${SEC_$packname} \"$packinfo\""
-      fi
+      case $op in
+        0)
+          packdesc=`grep -e '^Name:' "$found/packinfo/DESCRIPTION" | sed -e 's/^Name *: *//'`
+          packdesc_low=`echo $packdesc | sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+          packver=`grep -e '^Version:' "$found/packinfo/DESCRIPTION" | sed -e 's/^Version *: *//'`
+          packinstdir=$packdesc_low-$packver
+          if test "$packdesc_low" = "windows" -o "$packdesc_low" = "java" -o "$packdesc_low" = "arpack"; then
+            flag_=
+          else
+            flag_=$flag
+          fi
+          echo "Section $flag_ \"$packdesc\" SEC_$packname"
+          echo "  SetOverwrite try"
+          get_nsi_additional_files $packname
+          echo "  SetOutPath \"\$INSTDIR\\share\\octave\\packages\\$packinstdir\""
+          echo "  File /r \"\${OCTAVE_ROOT}\\share\\octave\\packages\\$packinstdir\\*\""
+          echo "SectionEnd"
+          ;;
+        1)
+          packinfo=`sed -e '/^ /{H;$!d;}' -e 'x;/^Description: /!d;' "$found/packinfo/DESCRIPTION" | \
+            sed -e ':a;N;$!ba;s/\n */\ /g' | sed -e 's/^Description: //'`
+          echo "  !insertmacro MUI_DESCRIPTION_TEXT \${SEC_$packname} \"$packinfo\""
+          ;;
+        2)
+          sed -n -e 's/ *$//' \
+                 -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \
+                 -e 's/^depends: *//p' \
+              "$found/packinfo/DESCRIPTION" | \
+            awk -F ', ' '{c=split($0, s); for(n=1; n<=c; ++n) printf("%s\n", s[n]) }' | \
+            sed -n -e 's/^octave.*$//' \
+                   -e "s/\([a-zA-Z0-9_]\+\) *\(( *\([<>]=\?\) *\([0-9]\+\.[0-9]\+\.[0-9]\+\) *) *\)\?/  !insertmacro CheckDependency \${SEC_$packname} \${SEC_\1}/p"
+          ;;
+      esac
     fi
   done
 }
@@ -1650,13 +1675,19 @@
       echo "$packfiles" > octave_pkg_${packname}_files.nsi
       packfiles="!include \\\"octave_pkg_${packname}_files.nsi\\\""
     fi
+    packdeps=`get_nsi_dependencies $packname "$found/packinfo/DESCRIPTION"`
+    if test ! -z "$packdeps"; then
+      echo "$packdeps" > octave_pkg_${packname}_deps.nsi
+      packdeps="!include \\\"octave_pkg_${packname}_deps.nsi\\\""
+    fi
     sed -e "s/@PACKAGE_NAME@/$packname/" \
         -e "s/@PACKAGE_LONG_NAME@/$packdesc/" \
         -e "s/@PACKAGE_VERSION@/$packver/" \
         -e "s/@PACKAGE_INFO@/$packinfo/" \
         -e "s/@OCTAVE_VERSION@/$octave_version/" \
         -e "s/@VCLIBS_ROOT@/$tdir_w32/" \
-	-e "s/@PACKAGE_FILES@/$packfiles/" \
+        -e "s/@PACKAGE_FILES@/$packfiles/" \
+        -e "s/@PACKAGE_DEPENDENCY@/$packdeps/" \
         -e "s/@SOFTWARE_ROOT@/$software_root/" octave_package.nsi.in > octave_pkg_$packname.nsi
     echo "done"
   fi
@@ -1694,33 +1725,50 @@
     echo "Software directory not found"
     exit -1
   fi
-  echo -n "creating octave_main.nsi... "
-  sed -e "s/@OCTAVE_VERSION@/$octave_version/" -e "s/@VCLIBS_ROOT@/$tdir_w32/" \
-    -e "s/@MSYS_ROOT@/$msys_root/" -e "s/@JHANDLES_VERSION@/$jhandles_version/" \
-    -e "s/@SOFTWARE_ROOT@/$software_root/" octave.nsi.in > octave_main.nsi
-  echo "done"
-  echo -n "creating octave_forge.nsi... "
-  echo "SectionGroup \"Main\" GRP_forge_main" > octave_forge.nsi
-  create_nsi_entries "$main_pkgs" "" >> octave_forge.nsi
-  echo "SectionGroupEnd" >> octave_forge.nsi
-  echo "SectionGroup \"Extra\" GRP_forge_extra" >> octave_forge.nsi
-  create_nsi_entries "$extra_pkgs" "/o" >> octave_forge.nsi
-  echo "SectionGroupEnd" >> octave_forge.nsi
-  echo "SectionGroup \"Language\" GRP_forge_lang" >> octave_forge.nsi
-  create_nsi_entries "$lang_pkgs" "/o" >> octave_forge.nsi
-  echo "SectionGroupEnd" >> octave_forge.nsi
-  echo "SectionGroup \"Others\" GRP_forge_others" >> octave_forge.nsi
-  create_nsi_entries "$nonfree_pkgs" "" >> octave_forge.nsi
-  echo "SectionGroupEnd" >> octave_forge.nsi
-  echo "done"
-  echo -n "creating octave_forge_desc.nsi... "
-  echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_main} \"\"" > octave_forge_desc.nsi
-  echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_extra} \"\"" > octave_forge_desc.nsi
-  echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_lang} \"\"" > octave_forge_desc.nsi
-  echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_others} \"\"" > octave_forge_desc.nsi
-  create_nsi_entries "$main_pkgs" "" 1 >> octave_forge_desc.nsi
-  create_nsi_entries "$extra_pkgs" "" 1 >> octave_forge_desc.nsi
-  echo "done"
+  if test ! -f "octave_main.nsi"; then
+    echo -n "creating octave_main.nsi... "
+    sed -e "s/@OCTAVE_VERSION@/$octave_version/" -e "s/@VCLIBS_ROOT@/$tdir_w32/" \
+      -e "s/@MSYS_ROOT@/$msys_root/" -e "s/@JHANDLES_VERSION@/$jhandles_version/" \
+      -e "s/@SOFTWARE_ROOT@/$software_root/" octave.nsi.in > octave_main.nsi
+    echo "done"
+  fi
+  if test ! -f "octave_forge.nsi"; then
+    echo -n "creating octave_forge.nsi... "
+    echo "SectionGroup \"Main\" GRP_forge_main" > octave_forge.nsi
+    create_nsi_entries "$main_pkgs" "" 0 >> octave_forge.nsi
+    echo "SectionGroupEnd" >> octave_forge.nsi
+    echo "SectionGroup \"Extra\" GRP_forge_extra" >> octave_forge.nsi
+    create_nsi_entries "$extra_pkgs" "/o" 0 >> octave_forge.nsi
+    echo "SectionGroupEnd" >> octave_forge.nsi
+    echo "SectionGroup \"Language\" GRP_forge_lang" >> octave_forge.nsi
+    create_nsi_entries "$lang_pkgs" "/o" 0 >> octave_forge.nsi
+    echo "SectionGroupEnd" >> octave_forge.nsi
+    echo "SectionGroup \"Others\" GRP_forge_others" >> octave_forge.nsi
+    create_nsi_entries "$nonfree_pkgs" "" 0 >> octave_forge.nsi
+    echo "SectionGroupEnd" >> octave_forge.nsi
+    echo "done"
+  fi
+  if test ! -f "octave_forge_deps.nsi"; then
+    echo -n "creating octave_forge_deps.nsi... "
+    echo "# Dependency checking" > octave_forge_deps.nsi
+    create_nsi_entries "$main_pkgs" "" 2 >> octave_forge_deps.nsi
+    create_nsi_entries "$extra_pkgs" "" 2 >> octave_forge_deps.nsi
+    create_nsi_entries "$lang_pkgs" "" 2 >> octave_forge_deps.nsi
+    create_nsi_entries "$nonfree_pkgs" "" 2 >> octave_forge_deps.nsi
+    echo "done"
+  fi
+  if test ! -f "octave_forge_desc.nsi"; then
+    echo -n "creating octave_forge_desc.nsi... "
+    echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_main} \"\"" > octave_forge_desc.nsi
+    echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_extra} \"\"" >> octave_forge_desc.nsi
+    echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_lang} \"\"" >> octave_forge_desc.nsi
+    echo "  !insertmacro MUI_DESCRIPTION_TEXT \${GRP_forge_others} \"\"" >> octave_forge_desc.nsi
+    create_nsi_entries "$main_pkgs" "" 1 >> octave_forge_desc.nsi
+    create_nsi_entries "$extra_pkgs" "" 1 >> octave_forge_desc.nsi
+    create_nsi_entries "$lang_pkgs" "" 1 >> octave_forge_desc.nsi
+    create_nsi_entries "$nonfree_pkgs" "" 1 >> octave_forge_desc.nsi
+    echo "done"
+  fi
   for pack in $isolated_packages; do
     create_nsi_package_file $pack
   done