Added deploy scripts from go-build

pull/437/head
obscuren 10 years ago
parent c27c2be584
commit 70cbfb199d
  1. 2
      .gitignore
  2. 16
      deploy/.gitignore
  3. 55
      deploy/README.md
  4. BIN
      deploy/osx/Ethereal.icns
  5. BIN
      deploy/osx/Mist.icns
  6. BIN
      deploy/osx/background-source-pm.pxm
  7. BIN
      deploy/osx/background-source.psd
  8. BIN
      deploy/osx/background.png
  9. BIN
      deploy/osx/background@2x.png
  10. 238
      deploy/osx/build.py
  11. 10
      deploy/osx/dmg_spec.json
  12. 35
      deploy/osx/script.sh
  13. 39
      deploy/windows/build.bat
  14. 111
      deploy/windows/create-setup.nsi
  15. BIN
      deploy/windows/ethereum.bmp
  16. BIN
      deploy/windows/logo.ico

2
.gitignore vendored

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

16
deploy/.gitignore vendored

@ -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

@ -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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 KiB

@ -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)

@ -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" }
]
}

@ -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

@ -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%

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Loading…
Cancel
Save