From 280bd5bb982cf7526ce01a5344f2fe669d55d076 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 22 Oct 2010 22:31:04 +0000 Subject: [PATCH] Improve the OS X installer Major changes are: * Version number now includes full GHC version and arch * Uninstaller copes with multiple versions --- configure.ac | 2 +- distrib/MacOS/GHC-relocatable.pmdoc/01ghc.xml | 2 +- distrib/MacOS/GHC-system.pmdoc/01ghc.xml | 2 +- .../GHC-system.pmdoc/{index.xml => index.xml.in} | 2 +- distrib/MacOS/GHC.xcodeproj/project.pbxproj | 4 +- distrib/MacOS/Makefile | 20 +++-- distrib/MacOS/installer-scripts/Uninstaller | 75 ---------------- distrib/MacOS/installer-scripts/Uninstaller.in | 91 ++++++++++++++++++++ distrib/MacOS/installer-scripts/create-links.in | 6 +- 9 files changed, 111 insertions(+), 93 deletions(-) rename distrib/MacOS/GHC-system.pmdoc/{index.xml => index.xml.in} (90%) delete mode 100644 distrib/MacOS/installer-scripts/Uninstaller create mode 100644 distrib/MacOS/installer-scripts/Uninstaller.in diff --git a/configure.ac b/configure.ac index b281cd8..7d1cdf2 100644 --- a/configure.ac +++ b/configure.ac @@ -950,7 +950,7 @@ if grep ' ' compiler/ghc.cabal.in 2>&1 >/dev/null; then AC_MSG_ERROR([compiler/ghc.cabal.in contains tab characters; please remove them]) fi -AC_CONFIG_FILES([mk/config.mk mk/install.mk mk/project.mk compiler/ghc.cabal ghc/ghc-bin.cabal utils/runghc/runghc.cabal ghc.spec extra-gcc-opts docs/users_guide/ug-book.xml docs/users_guide/ug-ent.xml docs/index.html libraries/prologue.txt distrib/ghc.iss distrib/configure.ac distrib/MacOS/installer-scripts/create-links]) +AC_CONFIG_FILES([mk/config.mk mk/install.mk mk/project.mk compiler/ghc.cabal ghc/ghc-bin.cabal utils/runghc/runghc.cabal ghc.spec extra-gcc-opts docs/users_guide/ug-book.xml docs/users_guide/ug-ent.xml docs/index.html libraries/prologue.txt distrib/ghc.iss distrib/configure.ac distrib/MacOS/installer-scripts/create-links distrib/MacOS/installer-scripts/Uninstaller distrib/MacOS/GHC-system.pmdoc/index.xml]) AC_CONFIG_COMMANDS([mk/stamp-h],[echo timestamp > mk/stamp-h]) AC_OUTPUT diff --git a/distrib/MacOS/GHC-relocatable.pmdoc/01ghc.xml b/distrib/MacOS/GHC-relocatable.pmdoc/01ghc.xml index a414253..6ad037d 100644 --- a/distrib/MacOS/GHC-relocatable.pmdoc/01ghc.xml +++ b/distrib/MacOS/GHC-relocatable.pmdoc/01ghc.xml @@ -1 +1 @@ -org.haskell.ghc.pkg1build/Release/GHC.framework/Library/Frameworksparentscripts.postinstall.pathrequireAuthorizationscripts.scriptsDirectoryPath.isRelativeTypescripts.postinstall.isRelativeTypeinstallTo.isRelativeTypescripts.postinstall.isAbsoluteTyperelocatableinstallFrom.isRelativeTypeinstallFrom.pathinstallToinstaller-scripts/relocateinstaller-scripts/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file +org.haskell.ghc.pkg1build/Release/GHC.framework/Library/Frameworksparentscripts.postinstall.pathrequireAuthorizationscripts.scriptsDirectoryPath.isRelativeTypescripts.postinstall.isRelativeTypeinstallTo.isRelativeTypescripts.postinstall.isAbsoluteTyperelocatableinstallFrom.isRelativeTypeinstallFrom.pathinstallToinstaller-scripts/relocateinstaller-scripts/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/distrib/MacOS/GHC-system.pmdoc/01ghc.xml b/distrib/MacOS/GHC-system.pmdoc/01ghc.xml index 9963fb1..4eb91c3 100644 --- a/distrib/MacOS/GHC-system.pmdoc/01ghc.xml +++ b/distrib/MacOS/GHC-system.pmdoc/01ghc.xml @@ -1 +1 @@ -org.haskell.ghc.pkg1.0/tmp/GHC.dst/Library/Frameworks/GHC.framework/Library/Frameworksscripts.scriptsDirectoryPath.pathparentidentifierscripts.postinstall.pathinstaller-scripts/create-linksinstaller-scripts01ghc-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file +org.haskell.ghc.pkg1.0/tmp/GHC.dst/Library/Frameworks/GHC.framework/Library/Frameworksscripts.scriptsDirectoryPath.pathparentidentifierscripts.postinstall.pathinstaller-scripts/create-linksinstaller-scripts01ghc-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/distrib/MacOS/GHC-system.pmdoc/index.xml b/distrib/MacOS/GHC-system.pmdoc/index.xml.in similarity index 90% rename from distrib/MacOS/GHC-system.pmdoc/index.xml rename to distrib/MacOS/GHC-system.pmdoc/index.xml.in index ba5f836..2e90ba6 100644 --- a/distrib/MacOS/GHC-system.pmdoc/index.xml +++ b/distrib/MacOS/GHC-system.pmdoc/index.xml.in @@ -28,4 +28,4 @@ in a web browser. More documentation is available online at\ \ To uninstall, execute\ \ - /Library/Frameworks/GHC.framework/Tools/Uninstaller}]]>01ghc.xmlproperties.systemDomainproperties.titleproperties.userDomainproperties.anywhereDomaindescription + /Library/Frameworks/GHC.framework/Versions/@ProjectVersion@-@TargetArch_CPP@/Tools/Uninstaller}]]>01ghc.xmlproperties.systemDomainproperties.titleproperties.userDomainproperties.anywhereDomaindescription diff --git a/distrib/MacOS/GHC.xcodeproj/project.pbxproj b/distrib/MacOS/GHC.xcodeproj/project.pbxproj index 0b2e480..6cd8658 100644 --- a/distrib/MacOS/GHC.xcodeproj/project.pbxproj +++ b/distrib/MacOS/GHC.xcodeproj/project.pbxproj @@ -74,7 +74,7 @@ ); buildRules = ( ); - comments = "Supported targets: build\n\nPrecondition: Fully compiled tree (i.e., \"perl boot; ./configure; make\" was already executed)\n\nThis project creates a Mac OS X framework that encapsulates a *relocatable* *binary* GHC distribution.\n\n* The framework is versioned using GHC's ProjectVersionInt. and we call the current version directory in the following CONTENTS_FOLDER_BUILD.\n\n* This target installs into CONTENTS_FOLDER_BUILD/ghc/ the same contents that is in a binary-dist tar ball.\n\n* The idea is that at framework installation time, a post install script will perform \n\n ./configure --prefix=CONTENTS_FOLDER_INSTALL/usr; make install \n\n in that ghc/ directory, where CONTENTS_FOLDER_INSTALL is the path that CONTENTS_FOLDER_BUILD has after the package containing the framework was installed by the package installer. This effectively rellocates the ghc installation to its final destination."; + comments = "Supported targets: build\n\nPrecondition: Fully compiled tree (i.e., \"perl boot; ./configure; make\" was already executed)\n\nThis project creates a Mac OS X framework that encapsulates a *relocatable* *binary* GHC distribution.\n\n* The framework is versioned using GHC's version and platform, and we call the current version directory in the following CONTENTS_FOLDER_BUILD.\n\n* This target installs into CONTENTS_FOLDER_BUILD/ghc/ the same contents that is in a binary-dist tar ball.\n\n* The idea is that at framework installation time, a post install script will perform \n\n ./configure --prefix=CONTENTS_FOLDER_INSTALL/usr; make install \n\n in that ghc/ directory, where CONTENTS_FOLDER_INSTALL is the path that CONTENTS_FOLDER_BUILD has after the package containing the framework was installed by the package installer. This effectively rellocates the ghc installation to its final destination."; dependencies = ( ); name = "GHC-relocatable"; @@ -92,7 +92,7 @@ ); buildRules = ( ); - comments = "Supported targets: build, install\n\nPrecondition: We are in a distribution tree, not a vanilla tree from darcs - i.e., \"perl boot; ./configure\" was already executed.\n\nAs part of the build target, ./configure will be executed again (setting a --prefix). Additional arguments to ./configure can be specified by way of the environment variable XCODE_EXTRA_CONFIGURE_ARGS.\n\nThis project creates a Mac OS X framework at /Library/Frameworks.\n\n* The framework is versioned using GHC's ProjectVersionInt.\n\n* The target configures the tree for the deployment location and builds the tree.\n\n* This target installs the framework not into its final destination, but into a build directory using the DESTDIR feature of GHC build system (unless the deployment flag in the build rules is set).\n\n* The idea is that the framework at the build location is being turned into a package and the package installer eventually puts its at its final destination. \n"; + comments = "Supported targets: build, install\n\nPrecondition: We are in a distribution tree, not a vanilla tree from darcs - i.e., \"perl boot; ./configure\" was already executed.\n\nAs part of the build target, ./configure will be executed again (setting a --prefix). Additional arguments to ./configure can be specified by way of the environment variable XCODE_EXTRA_CONFIGURE_ARGS.\n\nThis project creates a Mac OS X framework at /Library/Frameworks.\n\n* The framework is versioned using GHC's version and platform.\n\n* The target configures the tree for the deployment location and builds the tree.\n\n* This target installs the framework not into its final destination, but into a build directory using the DESTDIR feature of GHC build system (unless the deployment flag in the build rules is set).\n\n* The idea is that the framework at the build location is being turned into a package and the package installer eventually puts its at its final destination. \n"; dependencies = ( ); name = "GHC-systemwide"; diff --git a/distrib/MacOS/Makefile b/distrib/MacOS/Makefile index dbf7886..eef5661 100644 --- a/distrib/MacOS/Makefile +++ b/distrib/MacOS/Makefile @@ -28,20 +28,21 @@ endif include ../../mk/custom-settings.mk -# The ProjectVersionInt is GHC's idea of an API version and hence determines -# the framework version. -FRAMEWORK_VERSION = $(ProjectVersionInt) +# The framework version is a string like +# 7.0.1-i386 +# for an i386 build of GHC 7.0.1. It's used for the subdirectory of +# /Library/Frameworks/GHC.framework/Versions/ +FRAMEWORK_VERSION = $(ProjectVersion)-$(TargetArch_CPP) # Xcode requires CURRENT_PROJECT_VERSION to be an int or float. We use this # only as the build version (aka CFBundleVersion). CURRENT_PROJECT_VERSION = $(ProjectVersionInt).$(ProjectPatchLevel) -# The user-visible CFBundleShortVersionString is set to the standard GHC -# version number. -SHORT_VERSION_STRING = $(ProjectVersion) +# The user-visible CFBundleShortVersionString +SHORT_VERSION_STRING = $(FRAMEWORK_VERSION) # Name of the installer package -PACKAGE_NAME = GHC-$(ProjectVersion)-$(TargetArch_CPP).pkg +PACKAGE_NAME = GHC-$(FRAMEWORK_VERSION).pkg # Determine arguments that should be passed to ./configure from within Xcode # @@ -69,7 +70,7 @@ endif DSTROOT=/tmp/GHC.dst # Tools directory for a system volume install -TOOLS_SYSTEM=$(DSTROOT)/Library/Frameworks/GHC.framework/Tools +TOOLS_SYSTEM=$(DSTROOT)/Library/Frameworks/GHC.framework/Versions/$(FRAMEWORK_VERSION)/Tools PACKAGEMAKER=/Developer/usr/bin/packagemaker @@ -87,6 +88,7 @@ framework-pkg: -$(RM) -rf $(DSTROOT) mkdir -p $(TOOLS_SYSTEM) cp installer-scripts/Uninstaller $(TOOLS_SYSTEM) + cp installer-scripts/create-links $(TOOLS_SYSTEM) xcodebuild -target GHC-systemwide clean build\ CURRENT_PROJECT_VERSION=$(CURRENT_PROJECT_VERSION)\ SHORT_VERSION_STRING=$(SHORT_VERSION_STRING)\ @@ -102,7 +104,7 @@ framework-pkg: -$(RM) -f GHC-system.pmdoc/*-contents.xml $(PACKAGEMAKER) -v --doc GHC-system.pmdoc\ $(PACKAGEMAKER_TARGET) -o $(TOP)/$(PACKAGE_NAME)\ - -i org.haskell.GHC.$(FRAMEWORK_VERSION) + -i org.haskell.ghc.$(FRAMEWORK_VERSION) # If we don't specify COMMAND_MODE=unix2003 then xcodebuild defaults # to setting it to legacy, which means that ar builds archives diff --git a/distrib/MacOS/installer-scripts/Uninstaller b/distrib/MacOS/installer-scripts/Uninstaller deleted file mode 100644 index 784c7c2..0000000 --- a/distrib/MacOS/installer-scripts/Uninstaller +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh - -# Uninstaller script for GHC.framework -# (currently only for system volume installations) - -INSTALL_DEST=/Library/Frameworks -INSTALL_BASE=/ - -if [ ${INSTALL_BASE} = / ]; then - INSTALL_BASE=/usr -fi -INSTALL_BIN=${INSTALL_BASE}/bin -INSTALL_MAN1=${INSTALL_BASE}/share/man/man1 -INSTALL_HTML=${INSTALL_BASE}/share/doc - -if [ ! -x ${INSTALL_DEST}/GHC.framework ]; then - echo "${INSTALL_DEST}/GHC.framework does not exit" - exit 1 -fi - -if [ ${USER} != root ]; then - echo "GHC.framework installer must be run with admin privileges" - echo "Prefix command by 'sudo'" - exit 1 -fi - -VERSIONS=(`ls ${INSTALL_DEST}/GHC.framework/Versions`) -NO_VERSIONS=${#VERSIONS[@]} - -if [ ${VERSIONS[${NO_VERSIONS}-1]} != Current ]; then - echo "Fatal error: last version should be Current" - echo "Found versions: ${VERSIONS[@]}" - exit 1 -fi -CURRENT_PHYS=`cd /Library/Frameworks/GHC.framework/Versions/Current; pwd -P` -CURRENT=`basename ${CURRENT_PHYS}` - -if [ ${NO_VERSIONS} -ne 2 ]; then - echo "Multiple versions of GHC.framework are currently installed." - echo "This uninstaller removes GHC.framework entirely and should only" - echo "be used if there is exactly one version." - echo - echo "To remove individual old versions, simply delete the directory" - echo "${INSTALL_DEST}/GHC.framework/Versions/VERSION_TO_REMOVE" - echo - echo "Found versions: ${VERSIONS[@]}(= ${CURRENT})" - exit 1 -fi - -echo "Removing symbolic links into GHC.framework" -for thisfile in ${INSTALL_BIN}/*; do - if ls -l "${thisfile}" | grep -q GHC.framework/Versions; then - rm -f "${thisfile}" - fi -done -for thisfile in ${INSTALL_MAN1}/*; do - if ls -l "${thisfile}" | grep -q GHC.framework/Versions; then - rm -f "${thisfile}" - fi -done -for thisfile in ${INSTALL_HTML}/*; do - if ls -l "${thisfile}" | grep -q GHC.framework/Versions; then - rm -f "${thisfile}" - fi -done - -echo "Removing ${INSTALL_DEST}/GHC.framework" -rm -rf ${INSTALL_DEST}/GHC.framework - -echo "Removing package recipt" -# The first is for Leopard packages and the second for Tiger packages. -rm -f /Library/Receipts/boms/org.haskell.ghc.pkg.bom -rm -rf /Library/Receipts/ghc.pkg - -echo "${INSTALL_DEST}/GHC.framework has been purged!" diff --git a/distrib/MacOS/installer-scripts/Uninstaller.in b/distrib/MacOS/installer-scripts/Uninstaller.in new file mode 100644 index 0000000..8774e07 --- /dev/null +++ b/distrib/MacOS/installer-scripts/Uninstaller.in @@ -0,0 +1,91 @@ +#!/bin/sh + +# Uninstaller script for GHC.framework +# (currently only for system volume installations) + +INSTALL_DEST=/Library/Frameworks +INSTALL_BASE=/ + +# Turn off things that might make /usr/bin/ls give funky output +unset CLICOLOR +unset CLICOLOR_FORCE +unset LSCOLORS + +if [ ${INSTALL_BASE} = / ]; then + INSTALL_BASE=/usr +fi +INSTALL_BIN=${INSTALL_BASE}/bin +INSTALL_MAN1=${INSTALL_BASE}/share/man/man1 +INSTALL_HTML=${INSTALL_BASE}/share/doc + +if [ ! -x ${INSTALL_DEST}/GHC.framework ]; then + echo "${INSTALL_DEST}/GHC.framework does not exit" + exit 1 +fi + +if [ ${USER} != root ]; then + echo "GHC.framework installer must be run with admin privileges" + echo "Prefix command by 'sudo'" + exit 1 +fi + +FRAMEWORK_DIRECTORY="$INSTALL_DEST/GHC.framework" +VERSIONS_DIRECTORY="$FRAMEWORK_DIRECTORY/Versions" + +MY_VERSION=@ProjectVersion@-@TargetArch_CPP@ +MY_DIRECTORY="$VERSIONS_DIRECTORY/$MY_VERSION" + +CURRENT_DIRECTORY="$VERSIONS_DIRECTORY/Current" +CURRENT_VERSION=`readlink "$CURRENT_DIRECTORY"` + +if [ "$CURRENT_VERSION" = "$MY_VERSION" ] +then + rm -f "$CURRENT_DIRECTORY" + + removeLinksFrom () { + for f in `ls -1 "$MY_DIRECTORY/$1"` + do + qf="$1/$f" + # Sanity check that it is a link like we expect + l=`readlink "$qf" | grep GHC.framework/Versions` + if [ "$l" != "" ] + then + rm -f "$qf" + fi + done + } + + removeLinksFrom /usr/bin + removeLinksFrom /usr/share/man/man1 + removeLinksFrom /usr/share/doc +fi + +echo "Removing $MY_DIRECTORY" +rm -rf "$MY_DIRECTORY" + +if [ "$CURRENT_VERSION" = "$MY_VERSION" ] +then + # This isn't ideal, but it's a vague approximation to + # "the most recent version": + NEW_VERSION=`ls -1 "$VERSIONS_DIRECTORY" | tail -1` + if [ "$NEW_VERSION" = "" ] + then + echo "Removing $FRAMEWORK_DIRECTORY" + rm -rf "$FRAMEWORK_DIRECTORY" + else + ln -s "$NEW_VERSION" "$CURRENT_DIRECTORY" + NEW_CREATE_LINKS="$VERSIONS_DIRECTORY/$NEW_VERSION/Tools/create-links" + if [ -f "$NEW_CREATE_LINKS" ] + then + sh "$NEW_CREATE_LINKS" + fi + fi +fi + +echo "Removing package receipt" +# The first is for Leopard packages and the second for Tiger packages. +rm -f "/Library/Receipts/boms/org.haskell.ghc.$MY_VERSION.bom" +rm -rf "/Library/Receipts/ghc.$MY_VERSION.pkg" + +echo "Done." + diff --git a/distrib/MacOS/installer-scripts/create-links.in b/distrib/MacOS/installer-scripts/create-links.in index 2e3dc5e..c12d90a 100644 --- a/distrib/MacOS/installer-scripts/create-links.in +++ b/distrib/MacOS/installer-scripts/create-links.in @@ -20,8 +20,8 @@ if [ "$INSTALL_BASE" = / ]; then INSTALL_BASE=/usr fi -ProjectVersionInt=@ProjectVersionInt@ -GHC_BASE="$INSTALL_DEST/GHC.framework/Versions/$ProjectVersionInt" +VERSION=@ProjectVersion@-@TargetArch_CPP@ +GHC_BASE="$INSTALL_DEST/GHC.framework/Versions/$VERSION" INSTALL_BIN="$INSTALL_BASE/bin" mkdir -p "$INSTALL_BIN" @@ -34,5 +34,5 @@ INSTALL_HTML="$INSTALL_BASE"/share/doc mkdir -p "$INSTALL_MAN1" if [ -d "$GHC_BASE"/usr/share/man/man1 ]; then ln -sf "$GHC_BASE"/usr/share/man/man1/* "$INSTALL_MAN1/" - ln -sf "$GHC_BASE"/usr/share/doc/ghc.$ProjectVersionInt "$INSTALL_HTML/" + ln -sf "$GHC_BASE"/usr/share/doc/ghc "$INSTALL_HTML/" fi -- 1.7.10.4