Browse Source

build: python 3 compatibility

Ubuntu 16.04 "xenial xerus" does not come with Python 2.x by default.
It is possible to install a python-2.7 package, but this has its own
problem: no `python` or `python2` symlink (see #7717).

This fixes the following scripts to work with python 3:
- `make check` (bctest,py, bitcoin-util-test.py)
- `make translate` (extract_strings_qt.py)
- `make symbols-check` (symbol-check.py)
- `make security-check` (security-check.py)

Explicitly call the python commands using $(PYTHON) instead
of relying on the interpreter line at the top of the scripts.
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
18f05c765c
  1. 6
      Makefile.am
  2. 2
      configure.ac
  3. 34
      contrib/devtools/security-check.py
  4. 63
      contrib/devtools/symbol-check.py
  5. 6
      contrib/macdeploy/custom_dsstore.py
  6. 136
      contrib/macdeploy/macdeployqtplus
  7. 9
      share/qt/extract_strings_qt.py
  8. 2
      src/Makefile.qt.include
  9. 2
      src/Makefile.test.include
  10. 2
      src/test/bctest.py
  11. 2
      src/test/bitcoin-util-test.py

6
Makefile.am

@ -110,7 +110,7 @@ osx_volname:
if BUILD_DARWIN if BUILD_DARWIN
$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING)
$(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2 -volname $(OSX_VOLNAME)
deploydir: $(OSX_DMG) deploydir: $(OSX_DMG)
else else
@ -134,10 +134,10 @@ $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIF
$(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@
$(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) $(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN)
$< "$@" "$(OSX_VOLNAME)" $(PYTHON) $< "$@" "$(OSX_VOLNAME)"
$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING)
INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2
deploydir: $(APP_DIST_EXTRAS) deploydir: $(APP_DIST_EXTRAS)
endif endif

2
configure.ac

@ -60,7 +60,7 @@ AC_PATH_TOOL(STRIP, strip)
AC_PATH_TOOL(GCOV, gcov) AC_PATH_TOOL(GCOV, gcov)
AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(LCOV, lcov)
AC_PATH_PROG(JAVA, java) AC_PATH_PROG(JAVA, java)
AC_PATH_PROG(PYTHON, python) AC_PATH_PROGS([PYTHON], [python3 python2.7 python2 python])
AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG(GENHTML, genhtml)
AC_PATH_PROG([GIT], [git]) AC_PATH_PROG([GIT], [git])
AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(CCACHE,ccache)

34
contrib/devtools/security-check.py

@ -5,7 +5,7 @@ Exit status will be 0 if successful, and the program will be silent.
Otherwise the exit status will be 1 and it will log which executables failed which checks. Otherwise the exit status will be 1 and it will log which executables failed which checks.
Needs `readelf` (for ELF) and `objdump` (for PE). Needs `readelf` (for ELF) and `objdump` (for PE).
''' '''
from __future__ import division,print_function from __future__ import division,print_function,unicode_literals
import subprocess import subprocess
import sys import sys
import os import os
@ -23,9 +23,9 @@ def check_ELF_PIE(executable):
raise IOError('Error opening file') raise IOError('Error opening file')
ok = False ok = False
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
line = line.split() line = line.split()
if len(line)>=2 and line[0] == 'Type:' and line[1] == 'DYN': if len(line)>=2 and line[0] == b'Type:' and line[1] == b'DYN':
ok = True ok = True
return ok return ok
@ -38,17 +38,17 @@ def get_ELF_program_headers(executable):
in_headers = False in_headers = False
count = 0 count = 0
headers = [] headers = []
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
if line.startswith('Program Headers:'): if line.startswith(b'Program Headers:'):
in_headers = True in_headers = True
if line == '': if line == b'':
in_headers = False in_headers = False
if in_headers: if in_headers:
if count == 1: # header line if count == 1: # header line
ofs_typ = line.find('Type') ofs_typ = line.find(b'Type')
ofs_offset = line.find('Offset') ofs_offset = line.find(b'Offset')
ofs_flags = line.find('Flg') ofs_flags = line.find(b'Flg')
ofs_align = line.find('Align') ofs_align = line.find(b'Align')
if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1: if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1:
raise ValueError('Cannot parse elfread -lW output') raise ValueError('Cannot parse elfread -lW output')
elif count > 1: elif count > 1:
@ -65,9 +65,9 @@ def check_ELF_NX(executable):
have_wx = False have_wx = False
have_gnu_stack = False have_gnu_stack = False
for (typ, flags) in get_ELF_program_headers(executable): for (typ, flags) in get_ELF_program_headers(executable):
if typ == 'GNU_STACK': if typ == b'GNU_STACK':
have_gnu_stack = True have_gnu_stack = True
if 'W' in flags and 'E' in flags: # section is both writable and executable if b'W' in flags and b'E' in flags: # section is both writable and executable
have_wx = True have_wx = True
return have_gnu_stack and not have_wx return have_gnu_stack and not have_wx
@ -84,7 +84,7 @@ def check_ELF_RELRO(executable):
# However, the dynamic linker need to write to this area so these are RW. # However, the dynamic linker need to write to this area so these are RW.
# Glibc itself takes care of mprotecting this area R after relocations are finished. # Glibc itself takes care of mprotecting this area R after relocations are finished.
# See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347 # See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347
if typ == 'GNU_RELRO': if typ == b'GNU_RELRO':
have_gnu_relro = True have_gnu_relro = True
have_bindnow = False have_bindnow = False
@ -92,9 +92,9 @@ def check_ELF_RELRO(executable):
(stdout, stderr) = p.communicate() (stdout, stderr) = p.communicate()
if p.returncode: if p.returncode:
raise IOError('Error opening file') raise IOError('Error opening file')
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
tokens = line.split() tokens = line.split()
if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]): if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2]):
have_bindnow = True have_bindnow = True
return have_gnu_relro and have_bindnow return have_gnu_relro and have_bindnow
@ -107,8 +107,8 @@ def check_ELF_Canary(executable):
if p.returncode: if p.returncode:
raise IOError('Error opening file') raise IOError('Error opening file')
ok = False ok = False
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
if '__stack_chk_fail' in line: if b'__stack_chk_fail' in line:
ok = True ok = True
return ok return ok

63
contrib/devtools/symbol-check.py

@ -11,7 +11,7 @@ Example usage:
find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
''' '''
from __future__ import division, print_function from __future__ import division, print_function, unicode_literals
import subprocess import subprocess
import re import re
import sys import sys
@ -47,28 +47,28 @@ MAX_VERSIONS = {
# Ignore symbols that are exported as part of every executable # Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = { IGNORE_EXPORTS = {
'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used' b'_edata', b'_end', b'_init', b'__bss_start', b'_fini', b'_IO_stdin_used'
} }
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
# Allowed NEEDED libraries # Allowed NEEDED libraries
ALLOWED_LIBRARIES = { ALLOWED_LIBRARIES = {
# bitcoind and bitcoin-qt # bitcoind and bitcoin-qt
'libgcc_s.so.1', # GCC base support b'libgcc_s.so.1', # GCC base support
'libc.so.6', # C library b'libc.so.6', # C library
'libpthread.so.0', # threading b'libpthread.so.0', # threading
'libanl.so.1', # DNS resolve b'libanl.so.1', # DNS resolve
'libm.so.6', # math library b'libm.so.6', # math library
'librt.so.1', # real-time (clock) b'librt.so.1', # real-time (clock)
'ld-linux-x86-64.so.2', # 64-bit dynamic linker b'ld-linux-x86-64.so.2', # 64-bit dynamic linker
'ld-linux.so.2', # 32-bit dynamic linker b'ld-linux.so.2', # 32-bit dynamic linker
# bitcoin-qt only # bitcoin-qt only
'libX11-xcb.so.1', # part of X11 b'libX11-xcb.so.1', # part of X11
'libX11.so.6', # part of X11 b'libX11.so.6', # part of X11
'libxcb.so.1', # part of X11 b'libxcb.so.1', # part of X11
'libfontconfig.so.1', # font support b'libfontconfig.so.1', # font support
'libfreetype.so.6', # font parsing b'libfreetype.so.6', # font parsing
'libdl.so.2' # programming interface to dynamic linker b'libdl.so.2' # programming interface to dynamic linker
} }
class CPPFilt(object): class CPPFilt(object):
@ -81,7 +81,8 @@ class CPPFilt(object):
self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE) self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
def __call__(self, mangled): def __call__(self, mangled):
self.proc.stdin.write(mangled + '\n') self.proc.stdin.write(mangled + b'\n')
self.proc.stdin.flush()
return self.proc.stdout.readline().rstrip() return self.proc.stdout.readline().rstrip()
def close(self): def close(self):
@ -99,24 +100,24 @@ def read_symbols(executable, imports=True):
if p.returncode: if p.returncode:
raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip()))
syms = [] syms = []
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
line = line.split() line = line.split()
if len(line)>7 and re.match('[0-9]+:$', line[0]): if len(line)>7 and re.match(b'[0-9]+:$', line[0]):
(sym, _, version) = line[7].partition('@') (sym, _, version) = line[7].partition(b'@')
is_import = line[6] == 'UND' is_import = line[6] == b'UND'
if version.startswith('@'): if version.startswith(b'@'):
version = version[1:] version = version[1:]
if is_import == imports: if is_import == imports:
syms.append((sym, version)) syms.append((sym, version))
return syms return syms
def check_version(max_versions, version): def check_version(max_versions, version):
if '_' in version: if b'_' in version:
(lib, _, ver) = version.rpartition('_') (lib, _, ver) = version.rpartition(b'_')
else: else:
lib = version lib = version
ver = '0' ver = '0'
ver = tuple([int(x) for x in ver.split('.')]) ver = tuple([int(x) for x in ver.split(b'.')])
if not lib in max_versions: if not lib in max_versions:
return False return False
return ver <= max_versions[lib] return ver <= max_versions[lib]
@ -127,10 +128,10 @@ def read_libraries(filename):
if p.returncode: if p.returncode:
raise IOError('Error opening file') raise IOError('Error opening file')
libraries = [] libraries = []
for line in stdout.split('\n'): for line in stdout.split(b'\n'):
tokens = line.split() tokens = line.split()
if len(tokens)>2 and tokens[1] == '(NEEDED)': if len(tokens)>2 and tokens[1] == b'(NEEDED)':
match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) match = re.match(b'^Shared library: \[(.*)\]$', b' '.join(tokens[2:]))
if match: if match:
libraries.append(match.group(1)) libraries.append(match.group(1))
else: else:
@ -144,18 +145,18 @@ if __name__ == '__main__':
# Check imported symbols # Check imported symbols
for sym,version in read_symbols(filename, True): for sym,version in read_symbols(filename, True):
if version and not check_version(MAX_VERSIONS, version): if version and not check_version(MAX_VERSIONS, version):
print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym).decode('utf-8'), version.decode('utf-8')))
retval = 1 retval = 1
# Check exported symbols # Check exported symbols
for sym,version in read_symbols(filename, False): for sym,version in read_symbols(filename, False):
if sym in IGNORE_EXPORTS: if sym in IGNORE_EXPORTS:
continue continue
print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym).decode('utf-8')))
retval = 1 retval = 1
# Check dependency libraries # Check dependency libraries
for library_name in read_libraries(filename): for library_name in read_libraries(filename):
if library_name not in ALLOWED_LIBRARIES: if library_name not in ALLOWED_LIBRARIES:
print('%s: NEEDED library %s is not allowed' % (filename, library_name)) print('%s: NEEDED library %s is not allowed' % (filename, library_name.decode('utf-8')))
retval = 1 retval = 1
exit(retval) exit(retval)

6
contrib/macdeploy/custom_dsstore.py

@ -2,7 +2,7 @@
# Copyright (c) 2013-2015 The Bitcoin Core developers # Copyright (c) 2013-2015 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from __future__ import division,print_function,unicode_literals
import biplist import biplist
from ds_store import DSStore from ds_store import DSStore
from mac_alias import Alias from mac_alias import Alias
@ -14,7 +14,7 @@ package_name_ns = sys.argv[2]
ds = DSStore.open(output_file, 'w+') ds = DSStore.open(output_file, 'w+')
ds['.']['bwsp'] = { ds['.']['bwsp'] = {
'ShowStatusBar': False, 'ShowStatusBar': False,
'WindowBounds': '{{300, 280}, {500, 343}}', 'WindowBounds': b'{{300, 280}, {500, 343}}',
'ContainerShowSidebar': False, 'ContainerShowSidebar': False,
'SidebarWidth': 0, 'SidebarWidth': 0,
'ShowTabView': False, 'ShowTabView': False,
@ -28,7 +28,7 @@ icvp = {
'gridOffsetX': 0.0, 'gridOffsetX': 0.0,
'textSize': 12.0, 'textSize': 12.0,
'viewOptionsVersion': 1, 'viewOptionsVersion': 1,
'backgroundImageAlias': '\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00', 'backgroundImageAlias': b'\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00',
'backgroundColorBlue': 1.0, 'backgroundColorBlue': 1.0,
'iconSize': 96.0, 'iconSize': 96.0,
'backgroundColorGreen': 1.0, 'backgroundColorGreen': 1.0,

136
contrib/macdeploy/macdeployqtplus

@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import division, print_function, unicode_literals
# #
# Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org> # Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org>
# #
@ -201,7 +201,7 @@ class DeploymentInfo(object):
def getFrameworks(binaryPath, verbose): def getFrameworks(binaryPath, verbose):
if verbose >= 3: if verbose >= 3:
print "Inspecting with otool: " + binaryPath print("Inspecting with otool: " + binaryPath)
otoolbin=os.getenv("OTOOL", "otool") otoolbin=os.getenv("OTOOL", "otool")
otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o_stdout, o_stderr = otool.communicate() o_stdout, o_stderr = otool.communicate()
@ -222,8 +222,8 @@ def getFrameworks(binaryPath, verbose):
info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) info = FrameworkInfo.fromOtoolLibraryLine(line.strip())
if info is not None: if info is not None:
if verbose >= 3: if verbose >= 3:
print "Found framework:" print("Found framework:")
print info print(info)
libraries.append(info) libraries.append(info)
return libraries return libraries
@ -234,24 +234,24 @@ def runInstallNameTool(action, *args):
def changeInstallName(oldName, newName, binaryPath, verbose): def changeInstallName(oldName, newName, binaryPath, verbose):
if verbose >= 3: if verbose >= 3:
print "Using install_name_tool:" print("Using install_name_tool:")
print " in", binaryPath print(" in", binaryPath)
print " change reference", oldName print(" change reference", oldName)
print " to", newName print(" to", newName)
runInstallNameTool("change", oldName, newName, binaryPath) runInstallNameTool("change", oldName, newName, binaryPath)
def changeIdentification(id, binaryPath, verbose): def changeIdentification(id, binaryPath, verbose):
if verbose >= 3: if verbose >= 3:
print "Using install_name_tool:" print("Using install_name_tool:")
print " change identification in", binaryPath print(" change identification in", binaryPath)
print " to", id print(" to", id)
runInstallNameTool("id", id, binaryPath) runInstallNameTool("id", id, binaryPath)
def runStrip(binaryPath, verbose): def runStrip(binaryPath, verbose):
stripbin=os.getenv("STRIP", "strip") stripbin=os.getenv("STRIP", "strip")
if verbose >= 3: if verbose >= 3:
print "Using strip:" print("Using strip:")
print " stripped", binaryPath print(" stripped", binaryPath)
subprocess.check_call([stripbin, "-x", binaryPath]) subprocess.check_call([stripbin, "-x", binaryPath])
def copyFramework(framework, path, verbose): def copyFramework(framework, path, verbose):
@ -274,8 +274,8 @@ def copyFramework(framework, path, verbose):
shutil.copy2(fromPath, toPath) shutil.copy2(fromPath, toPath)
if verbose >= 3: if verbose >= 3:
print "Copied:", fromPath print("Copied:", fromPath)
print " to:", toPath print(" to:", toPath)
permissions = os.stat(toPath) permissions = os.stat(toPath)
if not permissions.st_mode & stat.S_IWRITE: if not permissions.st_mode & stat.S_IWRITE:
@ -288,14 +288,14 @@ def copyFramework(framework, path, verbose):
if not os.path.exists(linkfrom): if not os.path.exists(linkfrom):
os.symlink(linkto, linkfrom) os.symlink(linkto, linkfrom)
if verbose >= 2: if verbose >= 2:
print "Linked:", linkfrom, "->", linkto print("Linked:", linkfrom, "->", linkto)
fromResourcesDir = framework.sourceResourcesDirectory fromResourcesDir = framework.sourceResourcesDirectory
if os.path.exists(fromResourcesDir): if os.path.exists(fromResourcesDir):
toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory)
shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True) shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True)
if verbose >= 3: if verbose >= 3:
print "Copied resources:", fromResourcesDir print("Copied resources:", fromResourcesDir)
print " to:", toResourcesDir print(" to:", toResourcesDir)
fromContentsDir = framework.sourceVersionContentsDirectory fromContentsDir = framework.sourceVersionContentsDirectory
if not os.path.exists(fromContentsDir): if not os.path.exists(fromContentsDir):
fromContentsDir = framework.sourceContentsDirectory fromContentsDir = framework.sourceContentsDirectory
@ -304,16 +304,16 @@ def copyFramework(framework, path, verbose):
shutil.copytree(fromContentsDir, toContentsDir, symlinks=True) shutil.copytree(fromContentsDir, toContentsDir, symlinks=True)
contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory) contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory)
if verbose >= 3: if verbose >= 3:
print "Copied Contents:", fromContentsDir print("Copied Contents:", fromContentsDir)
print " to:", toContentsDir print(" to:", toContentsDir)
elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout)
qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib")
qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib")
if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath):
shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True) shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True)
if verbose >= 3: if verbose >= 3:
print "Copied for libQtGui:", qtMenuNibSourcePath print("Copied for libQtGui:", qtMenuNibSourcePath)
print " to:", qtMenuNibDestinationPath print(" to:", qtMenuNibDestinationPath)
return toPath return toPath
@ -326,7 +326,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym
deploymentInfo.deployedFrameworks.append(framework.frameworkName) deploymentInfo.deployedFrameworks.append(framework.frameworkName)
if verbose >= 2: if verbose >= 2:
print "Processing", framework.frameworkName, "..." print("Processing", framework.frameworkName, "...")
# Get the Qt path from one of the Qt frameworks # Get the Qt path from one of the Qt frameworks
if deploymentInfo.qtPath is None and framework.isQtFramework(): if deploymentInfo.qtPath is None and framework.isQtFramework():
@ -334,7 +334,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym
if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath): if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath):
if verbose >= 2: if verbose >= 2:
print framework.frameworkName, "already deployed, skipping." print(framework.frameworkName, "already deployed, skipping.")
continue continue
# install_name_tool the new id into the binary # install_name_tool the new id into the binary
@ -366,7 +366,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym
def deployFrameworksForAppBundle(applicationBundle, strip, verbose): def deployFrameworksForAppBundle(applicationBundle, strip, verbose):
frameworks = getFrameworks(applicationBundle.binaryPath, verbose) frameworks = getFrameworks(applicationBundle.binaryPath, verbose)
if len(frameworks) == 0 and verbose >= 1: if len(frameworks) == 0 and verbose >= 1:
print "Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path) print("Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path))
return DeploymentInfo() return DeploymentInfo()
else: else:
return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose)
@ -444,7 +444,7 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
for pluginDirectory, pluginName in plugins: for pluginDirectory, pluginName in plugins:
if verbose >= 2: if verbose >= 2:
print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..." print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...")
sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName)
destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory)
@ -454,8 +454,8 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
destinationPath = os.path.join(destinationDirectory, pluginName) destinationPath = os.path.join(destinationDirectory, pluginName)
shutil.copy2(sourcePath, destinationPath) shutil.copy2(sourcePath, destinationPath)
if verbose >= 3: if verbose >= 3:
print "Copied:", sourcePath print("Copied:", sourcePath)
print " to:", destinationPath print(" to:", destinationPath)
if strip: if strip:
runStrip(destinationPath, verbose) runStrip(destinationPath, verbose)
@ -525,7 +525,7 @@ if config.translations_dir and config.translations_dir[0]:
for p in config.add_resources: for p in config.add_resources:
if verbose >= 3: if verbose >= 3:
print "Checking for \"%s\"..." % p print("Checking for \"%s\"..." % p)
if not os.path.exists(p): if not os.path.exists(p):
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p)) sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p))
@ -535,7 +535,7 @@ for p in config.add_resources:
if len(config.fancy) == 1: if len(config.fancy) == 1:
if verbose >= 3: if verbose >= 3:
print "Fancy: Importing plistlib..." print("Fancy: Importing plistlib...")
try: try:
import plistlib import plistlib
except ImportError: except ImportError:
@ -545,7 +545,7 @@ if len(config.fancy) == 1:
p = config.fancy[0] p = config.fancy[0]
if verbose >= 3: if verbose >= 3:
print "Fancy: Loading \"%s\"..." % p print("Fancy: Loading \"%s\"..." % p)
if not os.path.exists(p): if not os.path.exists(p):
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p)) sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p))
@ -559,23 +559,23 @@ if len(config.fancy) == 1:
sys.exit(1) sys.exit(1)
try: try:
assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) assert "window_bounds" not in fancy or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4)
assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str) assert "background_picture" not in fancy or isinstance(fancy["background_picture"], str)
assert not fancy.has_key("icon_size") or isinstance(fancy["icon_size"], int) assert "icon_size" not in fancy or isinstance(fancy["icon_size"], int)
assert not fancy.has_key("applications_symlink") or isinstance(fancy["applications_symlink"], bool) assert "applications_symlink" not in fancy or isinstance(fancy["applications_symlink"], bool)
if fancy.has_key("items_position"): if "items_position" in fancy:
assert isinstance(fancy["items_position"], dict) assert isinstance(fancy["items_position"], dict)
for key, value in fancy["items_position"].iteritems(): for key, value in fancy["items_position"].items():
assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int) assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int)
except: except:
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p)) sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p))
sys.exit(1) sys.exit(1)
if fancy.has_key("background_picture"): if "background_picture" in fancy:
bp = fancy["background_picture"] bp = fancy["background_picture"]
if verbose >= 3: if verbose >= 3:
print "Fancy: Resolving background picture \"%s\"..." % bp print("Fancy: Resolving background picture \"%s\"..." % bp)
if not os.path.exists(bp): if not os.path.exists(bp):
bp = os.path.join(os.path.dirname(p), bp) bp = os.path.join(os.path.dirname(p), bp)
if not os.path.exists(bp): if not os.path.exists(bp):
@ -591,7 +591,7 @@ else:
if os.path.exists("dist"): if os.path.exists("dist"):
if verbose >= 2: if verbose >= 2:
print "+ Removing old dist folder +" print("+ Removing old dist folder +")
shutil.rmtree("dist") shutil.rmtree("dist")
@ -607,9 +607,9 @@ else:
target = os.path.join("dist", "Bitcoin-Qt.app") target = os.path.join("dist", "Bitcoin-Qt.app")
if verbose >= 2: if verbose >= 2:
print "+ Copying source bundle +" print("+ Copying source bundle +")
if verbose >= 3: if verbose >= 3:
print app_bundle, "->", target print(app_bundle, "->", target)
os.mkdir("dist") os.mkdir("dist")
shutil.copytree(app_bundle, target, symlinks=True) shutil.copytree(app_bundle, target, symlinks=True)
@ -619,7 +619,7 @@ applicationBundle = ApplicationBundleInfo(target)
# ------------------------------------------------ # ------------------------------------------------
if verbose >= 2: if verbose >= 2:
print "+ Deploying frameworks +" print("+ Deploying frameworks +")
try: try:
deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose)
@ -638,7 +638,7 @@ except RuntimeError as e:
if config.plugins: if config.plugins:
if verbose >= 2: if verbose >= 2:
print "+ Deploying plugins +" print("+ Deploying plugins +")
try: try:
deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose)
@ -664,7 +664,7 @@ else:
for lng_file in add_qt_tr: for lng_file in add_qt_tr:
p = os.path.join(qt_tr_dir, lng_file) p = os.path.join(qt_tr_dir, lng_file)
if verbose >= 3: if verbose >= 3:
print "Checking for \"%s\"..." % p print("Checking for \"%s\"..." % p)
if not os.path.exists(p): if not os.path.exists(p):
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file)) sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file))
@ -673,7 +673,7 @@ else:
# ------------------------------------------------ # ------------------------------------------------
if verbose >= 2: if verbose >= 2:
print "+ Installing qt.conf +" print("+ Installing qt.conf +")
f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb")
f.write(qt_conf) f.write(qt_conf)
@ -682,22 +682,22 @@ f.close()
# ------------------------------------------------ # ------------------------------------------------
if len(add_qt_tr) > 0 and verbose >= 2: if len(add_qt_tr) > 0 and verbose >= 2:
print "+ Adding Qt translations +" print("+ Adding Qt translations +")
for lng_file in add_qt_tr: for lng_file in add_qt_tr:
if verbose >= 3: if verbose >= 3:
print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file) print(os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file))
shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file)) shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file))
# ------------------------------------------------ # ------------------------------------------------
if len(config.add_resources) > 0 and verbose >= 2: if len(config.add_resources) > 0 and verbose >= 2:
print "+ Adding additional resources +" print("+ Adding additional resources +")
for p in config.add_resources: for p in config.add_resources:
t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p)) t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p))
if verbose >= 3: if verbose >= 3:
print p, "->", t print(p, "->", t)
if os.path.isdir(p): if os.path.isdir(p):
shutil.copytree(p, t, symlinks=True) shutil.copytree(p, t, symlinks=True)
else: else:
@ -706,10 +706,10 @@ for p in config.add_resources:
# ------------------------------------------------ # ------------------------------------------------
if config.sign and 'CODESIGNARGS' not in os.environ: if config.sign and 'CODESIGNARGS' not in os.environ:
print "You must set the CODESIGNARGS environment variable. Skipping signing." print("You must set the CODESIGNARGS environment variable. Skipping signing.")
elif config.sign: elif config.sign:
if verbose >= 1: if verbose >= 1:
print "Code-signing app bundle %s"%(target,) print("Code-signing app bundle %s"%(target,))
subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True) subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True)
# ------------------------------------------------ # ------------------------------------------------
@ -734,7 +734,7 @@ if config.dmg is not None:
def runHDIUtil(verb, image_basename, **kwargs): def runHDIUtil(verb, image_basename, **kwargs):
hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"]
if kwargs.has_key("capture_stdout"): if "capture_stdout" in kwargs:
del kwargs["capture_stdout"] del kwargs["capture_stdout"]
run = subprocess.check_output run = subprocess.check_output
else: else:
@ -744,7 +744,7 @@ if config.dmg is not None:
hdiutil_args.append("-verbose") hdiutil_args.append("-verbose")
run = subprocess.check_call run = subprocess.check_call
for key, value in kwargs.iteritems(): for key, value in kwargs.items():
hdiutil_args.append("-" + key) hdiutil_args.append("-" + key)
if not value is True: if not value is True:
hdiutil_args.append(str(value)) hdiutil_args.append(str(value))
@ -753,9 +753,9 @@ if config.dmg is not None:
if verbose >= 2: if verbose >= 2:
if fancy is None: if fancy is None:
print "+ Creating .dmg disk image +" print("+ Creating .dmg disk image +")
else: else:
print "+ Preparing .dmg disk image +" print("+ Preparing .dmg disk image +")
if config.dmg != "": if config.dmg != "":
dmg_name = config.dmg dmg_name = config.dmg
@ -770,7 +770,7 @@ if config.dmg is not None:
sys.exit(e.returncode) sys.exit(e.returncode)
else: else:
if verbose >= 3: if verbose >= 3:
print "Determining size of \"dist\"..." print("Determining size of \"dist\"...")
size = 0 size = 0
for path, dirs, files in os.walk("dist"): for path, dirs, files in os.walk("dist"):
for file in files: for file in files:
@ -778,14 +778,14 @@ if config.dmg is not None:
size += int(size * 0.15) size += int(size * 0.15)
if verbose >= 3: if verbose >= 3:
print "Creating temp image for modification..." print("Creating temp image for modification...")
try: try:
runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=volname, ov=True) runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=volname, ov=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
sys.exit(e.returncode) sys.exit(e.returncode)
if verbose >= 3: if verbose >= 3:
print "Attaching temp image..." print("Attaching temp image...")
try: try:
output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True) output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@ -796,13 +796,13 @@ if config.dmg is not None:
disk_name = m.group(1) disk_name = m.group(1)
if verbose >= 2: if verbose >= 2:
print "+ Applying fancy settings +" print("+ Applying fancy settings +")
if fancy.has_key("background_picture"): if "background_picture" in fancy:
bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"])) bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"]))
os.mkdir(os.path.dirname(bg_path)) os.mkdir(os.path.dirname(bg_path))
if verbose >= 3: if verbose >= 3:
print fancy["background_picture"], "->", bg_path print(fancy["background_picture"], "->", bg_path)
shutil.copy2(fancy["background_picture"], bg_path) shutil.copy2(fancy["background_picture"], bg_path)
else: else:
bg_path = None bg_path = None
@ -839,8 +839,8 @@ if config.dmg is not None:
itemscript = Template('set position of item "${item}" of container window to {${position}}') itemscript = Template('set position of item "${item}" of container window to {${position}}')
items_positions = [] items_positions = []
if fancy.has_key("items_position"): if "items_position" in fancy:
for name, position in fancy["items_position"].iteritems(): for name, position in fancy["items_position"].items():
params = { "item" : name, "position" : ",".join([str(p) for p in position]) } params = { "item" : name, "position" : ",".join([str(p) for p in position]) }
items_positions.append(itemscript.substitute(params)) items_positions.append(itemscript.substitute(params))
@ -851,9 +851,9 @@ if config.dmg is not None:
"background_commands" : "", "background_commands" : "",
"items_positions" : "\n ".join(items_positions) "items_positions" : "\n ".join(items_positions)
} }
if fancy.has_key("window_bounds"): if "window_bounds" in fancy:
params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]]) params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]])
if fancy.has_key("icon_size"): if "icon_size" in fancy:
params["icon_size"] = str(fancy["icon_size"]) params["icon_size"] = str(fancy["icon_size"])
if bg_path is not None: if bg_path is not None:
# Set background file, then call SetFile to make it invisible. # Set background file, then call SetFile to make it invisible.
@ -873,7 +873,7 @@ if config.dmg is not None:
print("Error running osascript.") print("Error running osascript.")
if verbose >= 2: if verbose >= 2:
print "+ Finalizing .dmg disk image +" print("+ Finalizing .dmg disk image +")
time.sleep(5) time.sleep(5)
try: try:
@ -886,6 +886,6 @@ if config.dmg is not None:
# ------------------------------------------------ # ------------------------------------------------
if verbose >= 2: if verbose >= 2:
print "+ Done +" print("+ Done +")
sys.exit(0) sys.exit(0)

9
share/qt/extract_strings_qt.py

@ -1,8 +1,9 @@
#!/usr/bin/python #!/usr/bin/python
''' '''
Extract _("...") strings for translation and convert to Qt4 stringdefs so that Extract _("...") strings for translation and convert to Qt stringdefs so that
they can be picked up by Qt linguist. they can be picked up by Qt linguist.
''' '''
from __future__ import division,print_function,unicode_literals
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import glob import glob
import operator import operator
@ -52,10 +53,14 @@ files = sys.argv[1:]
# xgettext -n --keyword=_ $FILES # xgettext -n --keyword=_ $FILES
XGETTEXT=os.getenv('XGETTEXT', 'xgettext') XGETTEXT=os.getenv('XGETTEXT', 'xgettext')
if not XGETTEXT:
print('Cannot extract strings: xgettext utility is not installed or not configured.',file=sys.stderr)
print('Please install package "gettext" and re-run \'./configure\'.',file=sys.stderr)
exit(1)
child = Popen([XGETTEXT,'--output=-','-n','--keyword=_'] + files, stdout=PIPE) child = Popen([XGETTEXT,'--output=-','-n','--keyword=_'] + files, stdout=PIPE)
(out, err) = child.communicate() (out, err) = child.communicate()
messages = parse_po(out) messages = parse_po(out.decode('utf-8'))
f = open(OUT_CPP, 'w') f = open(OUT_CPP, 'w')
f.write(""" f.write("""

2
src/Makefile.qt.include

@ -391,7 +391,7 @@ SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations" @test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
$(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" ../share/qt/extract_strings_qt.py $^ $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^
translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations" @test -n $(LUPDATE) || echo "lupdate is required for updating translations"

2
src/Makefile.test.include

@ -129,7 +129,7 @@ bitcoin_test_clean : FORCE
check-local: check-local:
@echo "Running test/bitcoin-util-test.py..." @echo "Running test/bitcoin-util-test.py..."
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
if EMBEDDED_UNIVALUE if EMBEDDED_UNIVALUE
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check

2
src/test/bctest.py

@ -1,7 +1,7 @@
# Copyright 2014 BitPay, Inc. # Copyright 2014 BitPay, Inc.
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from __future__ import division,print_function,unicode_literals
import subprocess import subprocess
import os import os
import json import json

2
src/test/bitcoin-util-test.py

@ -2,7 +2,7 @@
# Copyright 2014 BitPay, Inc. # Copyright 2014 BitPay, Inc.
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from __future__ import division,print_function,unicode_literals
import os import os
import bctest import bctest
import buildenv import buildenv

Loading…
Cancel
Save