Quellcode durchsuchen

Added deploy scripts from go-build

obscuren vor 10 Jahren
Ursprung
Commit
70cbfb199d

+ 2 - 0
.gitignore

@@ -21,3 +21,5 @@
 
 cmd/ethereum/ethereum
 cmd/mist/mist
+deploy/osx/Mist.app
+deploy/osx/Mist\ Installer.dmg

+ 16 - 0
deploy/.gitignore

@@ -0,0 +1,16 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+#
+# If you find yourself ignoring temporary files generated by your text editor
+# or operating system, you probably want to add a global ignore instead:
+#   git config --global core.excludesfile ~/.gitignore_global
+
+/tmp
+*/**/*un~
+*un~
+.DS_Store
+*/**/.DS_Store
+ethereum/ethereum
+ethereal/ethereal
+osx/Mist.app
+osx/__MACOSX
+osx/Mist.dmg

+ 55 - 0
deploy/README.md

@@ -0,0 +1,55 @@
+go-build
+========
+
+Build scripts for Ethereum Mist.
+
+### OS X
+Install all build dependencies.
+
+* brew install go gmp readline
+* npm install -g appdmg
+* go get -u github.com/ethereum/go-ethereum/cmd/mist
+* Open build.py and edit the (macdeployqt) paths.
+* python build.py
+
+If everything went ok you should now have a Mist.dmg file in your current folder.
+
+### Windows
+
+Install all build dependencies.
+
+* [Golang](http://golang.org/dl/) 1.2 or higher (32-bit required)
+* Install [Git](http://git-scm.com/) and [Mercurial](http://mercurial.selenic.com/)
+* [MinGW32](http://www.mingw.org/) (add X:\MinGW\bin directory to your  PATH)
+* Use mingw32-get to install *gmp* packages
+* Install [Qt5 for Windows 32-bit MinGW](http://qt-project.org/downloads) (5.2.1 at the moment of writing)
+* Install [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/) somewhere in your PATH. (read the [instructions](http://stackoverflow.com/questions/1710922/how-to-install-pkg-config-in-windows) here)
+* Install [NSIS](http://nsis.sourceforge.net/)
+
+After all these things have been satisfied ```go get -u github.com/ethereum/go-ethereum/cmd/mist```
+
+Once the compilation is completed you can create a setup binary.
+- Edit build.bat and change qtPath and mingwPath to the paths of your installed versions.
+- right-click the nsi file and select "Compile NSIS Script".
+
+If everything went well you should now have a windows-setup file.
+
+
+#### Troubleshooting
+
+Now it will be a miracle if the windows build works in one go.
+So here are some possible solutions for things that can go wrong:
+
+*Expected unqualified-id*
+```
+qopenglversionfunctions.h:785:43: error: expected unqualified-id before ')' token
+     void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);
+```
+
+See [this ticket](https://github.com/go-qml/qml/issues/56) for a couple of solutions.
+
+*pkg-config path*
+
+pkg-config might complain about the config path. Setup an environment value `PKG_CONFIG_PATH` and set it to `C:\Qt\Qt5.2.1\5.2.1\mingw48_32\lib\pkgconfig`. Adopted to your QT version.
+
+If there are any build problems please create an issue.

BIN
deploy/osx/Ethereal.icns


BIN
deploy/osx/Mist.icns


BIN
deploy/osx/background-source-pm.pxm


BIN
deploy/osx/background-source.psd


BIN
deploy/osx/background.png


BIN
deploy/osx/background@2x.png


+ 238 - 0
deploy/osx/build.py

@@ -0,0 +1,238 @@
+import sys, os, argparse, logging, shutil, subprocess, stat,glob
+from os.path import isfile
+
+# TODO handle icns
+# TODO create dmg
+# TODO Add client qml files and png files
+# CHMOD +x the main binary
+
+logging.basicConfig(
+    stream=sys.stdout,
+    format='%(asctime)s : %(levelname)s\t : %(message)s',
+    datefmt='%m/%d/%Y %I:%M:%S %p',
+    level=logging.DEBUG
+)
+
+XML_PLIST = """
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleGetInfoString</key>
+  <string>Mist</string>
+  <key>CFBundleExecutable</key>
+  <string>Mist</string>
+  <key>CFBundleIdentifier</key>
+  <string>com.ethereum.mist</string>
+  <key>CFBundleName</key>
+  <string>Mist</string>
+  <key>CFBundleIconFile</key>
+  <string>Mist.icns</string>
+  <key>CFBundleShortVersionString</key>
+  <string>POC8</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>POC8</string>
+  <key>CFBundlePackageType</key>
+  <string>APPL</string>
+  <key>IFMajorVersion</key>
+  <integer>0</integer>
+  <key>IFMinorVersion</key>
+  <integer>5</integer>
+</dict>
+</plist>
+"""
+
+RUN_SCRIPT ="""
+#!/bin/bash
+cd "${0%/*}"
+./go-ethereum
+"""
+
+class AppBundler:
+    def copytree(self, src, dst, symlinks=False, ignore=None):
+        for item in os.listdir(src):
+            s = os.path.join(src, item)
+            d = os.path.join(dst, item)
+            if os.path.isdir(s):
+                shutil.copytree(s, d, symlinks, ignore)
+            else:
+                shutil.copy2(s, d)
+
+    # If macdeployqt handles qmldir then runs on app
+    def runMacDeployQT(self):
+        exe = '/usr/local/opt/qt5/bin/macdeployqt'
+        if not os.path.exists(exe): exe = 'macdeployqt'
+        p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        handles_qml = False
+        for line in p.stdout.readlines():
+            if '-qmldir=<path>' in line:
+                handles_qml = True
+                break
+        if handles_qml and self.go_path is not None:
+            qml_path = os.path.join(self.go_path, 'src/github.com/ethereum/go-ethereum/cmd/mist/assets/qml/') #TODO this is terrible
+            out = os.path.join(self.output_dir + '/Mist.app')
+            command = exe + ' ' + out + ' -executable='+out+'/Contents/MacOS/Mist' + ' -qmldir=' +  qml_path #TODO this is terrible
+            logging.info('Running macdeployqt with options')
+            p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+            for line in p.stdout.readlines():
+                logging.info('macdeployqt: ' + line.strip())
+        else:
+            logging.error('Your version of macdeployqt does not handle qmldir')
+
+    # Add ICNS file to
+    def insertICNS(self):
+        path = os.path.join(self.output_dir, 'Mist.app/Contents/Resources/Mist.icns')
+
+        try:
+            shutil.copyfile('./Mist.icns',path) # TODO this is horrible
+            logging.info('Inserted Mist.icns')
+        except Exception as e:
+            logging.error(str(e))
+
+    def insertQMLnPNG(self):
+        pass # TODO
+
+    #def signApp(self):
+        # after macdeployqt copy /usr/local/opt/qt5/lib/QtCore.framework/Contents/Info.plist to .app/Contents/Resources/QtCore.framework/Resources/Info.plist
+        # codesign --verbose --force --sign "Developer ID Application: <<INSERT DETAILS HERE>>" /Users/_/Dropbox/Experiments/EthereumBuild/Ethereal.app/Contents/Frameworks/QtCore.framework
+        # do for rest
+        # codesign --verbose --deep --force --sign "Developer ID Application: <<INSERT DETAILS HERE>>" Ethereal.app
+        # codesign --verify --verbose=4 Ethereal.app
+
+    def insertAssets(self):
+        asset_path = os.path.join(self.go_path, 'src/github.com/ethereum/go-ethereum/cmd/mist/assets')
+        self.copytree(asset_path,"Mist.app/Contents/Resources/")
+        # Copy mnemonic word list
+        #shutil.copy(os.path.join(self.go_path, 'src/github.com/ethereum/eth-go/ethcrypto/mnemonic.words.lst'),"Mist.app/Contents/Resources/")
+
+    # Insert all QML files and other resource files Mist needs
+    def insertResources(self):
+        qml_path = os.path.join(self.go_path, 'src/github.com/ethereum/go-ethereum/cmd/mist/assets/qml/')
+        target_folder = "Mist.app/Contents/Resources/"
+        target_folder_qml = target_folder + "qml/"
+
+        os.makedirs(target_folder_qml)
+
+        files = glob.glob(qml_path)
+        for f in files:
+            print "Copying %s to %s" % (f, target_folder_qml)
+            if isfile(f):
+                shutil.copy(f, target_folder_qml)
+            else:
+                self.copytree(f, target_folder_qml)
+
+        files = glob.glob(os.path.join(self.go_path, 'src/github.com/ethereum/go-ethereum/cmd/mist/assets/*'))
+        for f in files:
+            print "Copying %s to %s" % (f, target_folder)
+            if isfile(f):
+                shutil.copy(f, target_folder)
+            else:
+                self.copytree(f, target_folder)
+    # Finds go-etherum binary and copies to app bundle
+
+    def insertGoBinary(self):
+        if self.go_path is not None:
+            binary = os.path.join(self.go_path, 'bin/mist')
+            if os.path.exists(binary):
+                try:
+                    shutil.copyfile(binary, os.path.join(self.output_dir, 'Mist.app/Contents/MacOS/Mist')) # TODO this is horrible
+                    os.chmod(os.path.join(self.output_dir, 'Mist.app/Contents/MacOS/Mist'), 0711)
+                    logging.info('Inserted go-ethereum binary')
+                except Exception as e:
+                    logging.error(str(e))
+            else:
+                logging.error('Cannot find go-etherum binary')
+                if self.handleHumanInput('Run "go get -u github.com/ethereum/go-ethereum" ?'):
+                    logging.debug('Not Implemented')
+                    pass
+        else:
+            logging.error('GOPATH not found, cannot continue')
+
+    # Write the Info.plist
+    def writePList(self):
+        try:
+            with open(os.path.join(self.output_dir, 'Mist.app/Contents/Info.plist'), 'wb') as f: # TODO this is horrible
+                f.write(XML_PLIST)
+                f.close()
+                logging.info('Info.plist written')
+        except Exception as e:
+            logging.error(str(e))
+
+    # Building out directory structure
+    def buildStructure(self, root, structure):
+        if root is not self.output_dir:
+            try:
+                os.mkdir(root)
+                logging.info('Created ' + root)
+            except Exception as e:
+                logging.error(str(e))
+                if self.handleHumanInput('Remove Directory?'):
+                    try:
+                        shutil.rmtree(root)
+                        self.buildStructure(root, structure)
+                        return
+                    except Exception as e:
+                        logging.error(str(e))
+        for item in structure.keys():
+            self.buildStructure(
+                os.path.join(root, item),
+                structure[item]
+            )
+
+    # Convert human input to boolean
+    def handleHumanInput(self, question=''):
+        if self.force: return True
+        try:
+            answer = raw_input(question + " [Y/n]: ").lower()
+        except:
+            return True
+        if answer is '' or answer[0:1] == 'y': return True
+        return False
+
+        logging.info('Copying QTWebProcess')
+        libexec_path = self.output_dir + '/Mist.app/Contents/libexec'
+        try:
+            os.mkdir(libexec_path)
+            shutil.copy2(path, libexec_path)
+            return True
+        except OSError as e:
+            print("Problem getting QTWebprocess on path %s. Error: %s" % (path, e))
+            return False
+
+    # Setup Variables
+    def __init__(self, args):
+        self.force = args['force']
+        self.output_dir = args['output']
+        self.app_name = "".join(x for x in args['name'] if x.isalnum()) # Simple Santize
+        self.app_structure = {
+            '%s.app' % self.app_name : {
+                'Contents' : {
+                    'MacOS' : {},
+                    'Resources' : {}
+                }
+            }
+        }
+        self.go_path = os.environ.get('GOPATH')
+        self.buildStructure(self.output_dir, self.app_structure)
+        self.writePList()
+        self.insertICNS()
+        self.insertGoBinary()
+        self.insertAssets()
+
+        #self.insertResources()
+
+        self.runMacDeployQT()
+        os.system("sh script.sh " + self.output_dir + "/Mist.app/Contents")
+        os.system("appdmg dmg_spec.json Mist.dmg")
+
+        logging.info("fin'")
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Standalone Mist Go Client App Bundler')
+    parser.add_argument('-n','--name', help='Name of app bundle', default='Mist', required=False)
+    parser.add_argument('-q','--qtwebpath', help='Location of QtWebProcess', default='Mist', required=False)
+    parser.add_argument('-o','--output', help='Directory to write app bundle', default=os.getcwd(), required=False)
+    parser.add_argument('-f','--force', help='Force Fresh Build', default=False, required=False)
+    args = vars(parser.parse_args())
+    AppBundler(args)

+ 10 - 0
deploy/osx/dmg_spec.json

@@ -0,0 +1,10 @@
+{
+  "title": "Mist Installer",
+  "icon": "Mist.icns",
+  "background": "background.png",
+  "icon-size": 144,
+  "contents": [
+    { "x": 900, "y": 244, "type": "link", "path": "/Applications" },
+    { "x": 140, "y": 244, "type": "file", "path": "Mist.app" }
+  ]
+}

+ 35 - 0
deploy/osx/script.sh

@@ -0,0 +1,35 @@
+#!/bin/bash
+
+BUILD_FOLDER_PATH=$1
+BUILD_QML_FOLDER_PATH="$BUILD_FOLDER_PATH/Resources/qml"
+BUILD_PLUGINS_FOLDER_PATH="$BUILD_FOLDER_PATH/PlugIns"
+
+declare -a BROKEN_FILES;
+k=0;
+for j in $(find ${BUILD_QML_FOLDER_PATH} -name *.dylib); do
+	BROKEN_FILES[${k}]=$j
+	
+	((k=k+1))
+done
+
+
+for i in "${BROKEN_FILES[@]}"; do
+	REPLACE_STRING="$BUILD_FOLDER_PATH/"
+	APP_CONTENT_FILE=${i//$REPLACE_STRING/""}
+	IFS='/' read -a array <<< "$APP_CONTENT_FILE"
+	LENGTH=${#array[@]}
+	LAST_ITEM_INDEX=$((LENGTH-1))
+	FILE=${array[${LENGTH} - 1]}
+	
+	ORIGINE_PATH=$(find ${BUILD_PLUGINS_FOLDER_PATH} -name ${FILE})
+	ORIGINE_PATH=${ORIGINE_PATH//$REPLACE_STRING/""}
+	s=""
+	for((l=0;l<${LAST_ITEM_INDEX};l++)) do
+		s=$s"../"
+	done
+	s=$s$ORIGINE_PATH
+	echo "s: $s"
+	
+	REMOVE_BROKEN_ALIAS=$(rm -rf $i)
+	RESULT=$(ln -s $s $i)
+done

+ 39 - 0
deploy/windows/build.bat

@@ -0,0 +1,39 @@
+@ECHO off
+set origin=%GOPATH%\src\github.com\ethereum\go-ethereum\cmd\mist
+set ethgo=%GOPATH%\src\github.com\ethereum\eth-go
+set target=%GOPATH%\pkg\ethereum\
+set qtPath=C:\Qt\Qt5.2.1\5.2.1\mingw48_32
+set mingwPath=C:\MingW\
+
+ECHO "Setting up Windows binaries"
+
+ECHO "Copying assets from %GOPATH%"
+xcopy /s %origin%\assets %target%assets
+
+ECHO "Copying mnemonic words"
+copy %ethgo%\ethcrypto\mnemonic.words.lst %target%
+
+ECHO "Compiling Mist"
+cd %origin%
+go install
+
+ECHO "Copying to source folder"
+copy %GOPATH%\bin\mist.exe %target%
+
+ECHO "Running QT Deploy"
+cd %target%
+windeployqt --webkit2 --qmldir=assets\qml\ .
+
+echo "Copy missing DLLs & Others"
+
+copy %qtPath%\bin\QtWebProcess.exe %target%
+copy %qtPath%\bin\Qt5MultimediaWidgets.dll %target%
+copy %qtPath%\bin\Qt5PrintSupport.dll %target%
+copy %qtPath%\bin\Qt5OpenGL.dll %target%
+copy %qtPath%\bin\Qt5WebKitWidgets.dll %target%
+
+copy %qtPath%\bin\libgcc_s_dw2-1.dll %target%
+copy "%qtPath%\bin\libstdc++-6.dll" %target%
+copy %qtPath%\bin\libwinpthread-1.dll %target%
+
+copy %mingwPath%\bin\libgmp-10.dll %target%

+ 111 - 0
deploy/windows/create-setup.nsi

@@ -0,0 +1,111 @@
+;--------------------------------
+;Include Modern UI
+
+  !include "MUI2.nsh"
+
+;--------------------------------
+;General
+
+  ;Name and file
+  Name "Mist"
+  OutFile "mist-setup.exe"
+
+  ;Default installation folder
+  InstallDir "$PROGRAMFILES\Mist"
+
+  ;Get installation folder from registry if available
+  InstallDirRegKey HKCU "Software\Mist" ""
+
+  ;Request application privileges for Windows Vista
+  RequestExecutionLevel admin
+
+  SetCompressor /SOLID lzma ; had the strongest compression rate for Mist
+
+;--------------------------------
+;Variables
+
+;--------------------------------
+;Interface Settings
+
+
+  !define MUI_ICON "logo.ico"
+  !define MUI_HEADERIMAGE
+  !define MUI_HEADERIMAGE_BITMAP "ethereum.bmp"
+  !define MUI_HEADERIMAGE_RIGHT
+  !define MUI_ABORTWARNING
+
+;--------------------------------
+;Pages
+
+  ;!insertmacro MUI_PAGE_LICENSE "tmp/LICENCE"
+  ;!insertmacro MUI_PAGE_COMPONENTS
+  !insertmacro MUI_PAGE_DIRECTORY
+
+  ;Start Menu Folder Page Configuration
+  !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
+  !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Mist"
+  !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
+
+  ;!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
+
+  !insertmacro MUI_PAGE_INSTFILES
+
+  !insertmacro MUI_UNPAGE_CONFIRM
+  !insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+;Languages
+
+  !insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+;Installer Sections
+
+Section
+
+  SetOutPath "$INSTDIR"
+
+  file /r $%GOPATH%\pkg\ethereum\*.*
+  file logo.ico
+
+  ;Store installation folder
+  WriteRegStr HKCU "Software\Mist" "" $INSTDIR
+
+  ;Create uninstaller
+  WriteUninstaller "$INSTDIR\Uninstall.exe"
+
+
+  CreateShortCut "$DESKTOP\Mist.lnk" "$INSTDIR\mist.exe" "" "$INSTDIR\logo.ico" 0
+
+  ;create start-menu items
+  CreateDirectory "$SMPROGRAMS\Mist"
+  CreateShortCut "$SMPROGRAMS\Mist\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
+  CreateShortCut "$SMPROGRAMS\Mist\Mist.lnk" "$INSTDIR\mist.exe" "" "$INSTDIR\logo.ico" 0
+
+SectionEnd
+
+;--------------------------------
+;Descriptions
+
+  ;Assign language strings to sections
+  ;!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+  ;  !insertmacro MUI_DESCRIPTION_TEXT ${SecDummy} $(DESC_SecDummy)
+  ;!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+
+  ;ADD YOUR OWN FILES HERE...
+  RMDir /r "$INSTDIR\*.*"
+
+  RMDir "$INSTDIR"
+
+  Delete "$DESKTOP\Mist.lnk"
+  Delete "$SMPROGRAMS\Mist\*.*"
+  RmDir  "$SMPROGRAMS\Mist"
+
+  DeleteRegKey /ifempty HKCU "Software\Mist"
+
+SectionEnd

BIN
deploy/windows/ethereum.bmp


BIN
deploy/windows/logo.ico