Merge branch 'master' of ssh://github.com/kivy/buildozer

This commit is contained in:
Mathieu Virbel 2014-09-22 22:41:36 +02:00
commit e375b93a2e
4 changed files with 72 additions and 69 deletions

View file

@ -553,6 +553,8 @@ class Buildozer(object):
source = join(cwd, source) source = join(cwd, source)
target = join(cwd, target) target = join(cwd, target)
self.debug('Rename {0} to {1}'.format(source, target)) self.debug('Rename {0} to {1}'.format(source, target))
if not os.path.isdir(os.path.dirname(target)):
self.error('Rename {0} to {1} fails becaues {2} is not a directory'.format(source, target, os.path.directory(target)))
rename(source, target) rename(source, target)
def file_copy(self, source, target, cwd=None): def file_copy(self, source, target, cwd=None):

View file

@ -78,7 +78,7 @@ try:
import errno import errno
import traceback import traceback
import signal import signal
except ImportError, e: except ImportError as e:
raise ImportError (str(e) + """ raise ImportError (str(e) + """
A critical module was not found. Probably this operating system does not A critical module was not found. Probably this operating system does not
@ -246,10 +246,10 @@ def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None
else: else:
raise TypeError ('The callback must be a string or function type.') raise TypeError ('The callback must be a string or function type.')
event_count = event_count + 1 event_count = event_count + 1
except TIMEOUT, e: except TIMEOUT as e:
child_result_list.append(child.before) child_result_list.append(child.before)
break break
except EOF, e: except EOF as e:
child_result_list.append(child.before) child_result_list.append(child.before)
break break
child_result = ''.join(child_result_list) child_result = ''.join(child_result_list)
@ -525,7 +525,7 @@ class spawn (object):
if self.use_native_pty_fork: if self.use_native_pty_fork:
try: try:
self.pid, self.child_fd = pty.fork() self.pid, self.child_fd = pty.fork()
except OSError, e: except OSError as e:
raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e))
else: # Use internal __fork_pty else: # Use internal __fork_pty
self.pid, self.child_fd = self.__fork_pty() self.pid, self.child_fd = self.__fork_pty()
@ -581,11 +581,11 @@ class spawn (object):
parent_fd, child_fd = os.openpty() parent_fd, child_fd = os.openpty()
if parent_fd < 0 or child_fd < 0: if parent_fd < 0 or child_fd < 0:
raise ExceptionPexpect, "Error! Could not open pty with os.openpty()." raise ExceptionPexpect("Error! Could not open pty with os.openpty().")
pid = os.fork() pid = os.fork()
if pid < 0: if pid < 0:
raise ExceptionPexpect, "Error! Failed os.fork()." raise ExceptionPexpect("Error! Failed os.fork().")
elif pid == 0: elif pid == 0:
# Child. # Child.
os.close(parent_fd) os.close(parent_fd)
@ -623,7 +623,7 @@ class spawn (object):
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY);
if fd >= 0: if fd >= 0:
os.close(fd) os.close(fd)
raise ExceptionPexpect, "Error! We are not disconnected from a controlling tty." raise ExceptionPexpect("Error! We are not disconnected from a controlling tty.")
except: except:
# Good! We are disconnected from a controlling tty. # Good! We are disconnected from a controlling tty.
pass pass
@ -631,14 +631,14 @@ class spawn (object):
# Verify we can open child pty. # Verify we can open child pty.
fd = os.open(child_name, os.O_RDWR); fd = os.open(child_name, os.O_RDWR);
if fd < 0: if fd < 0:
raise ExceptionPexpect, "Error! Could not open child pty, " + child_name raise ExceptionPexpect("Error! Could not open child pty, " + child_name)
else: else:
os.close(fd) os.close(fd)
# Verify we now have a controlling tty. # Verify we now have a controlling tty.
fd = os.open("/dev/tty", os.O_WRONLY) fd = os.open("/dev/tty", os.O_WRONLY)
if fd < 0: if fd < 0:
raise ExceptionPexpect, "Error! Could not open controlling tty, /dev/tty" raise ExceptionPexpect("Error! Could not open controlling tty, /dev/tty")
else: else:
os.close(fd) os.close(fd)
@ -826,7 +826,7 @@ class spawn (object):
if self.child_fd in r: if self.child_fd in r:
try: try:
s = os.read(self.child_fd, size) s = os.read(self.child_fd, size)
except OSError, e: # Linux does this except OSError as e: # Linux does this
self.flag_eof = True self.flag_eof = True
raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.') raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.')
if s == '': # BSD style if s == '': # BSD style
@ -834,10 +834,10 @@ class spawn (object):
raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.') raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.')
if self.logfile is not None: if self.logfile is not None:
self.logfile.write (s) self.logfile.write (s.decode(encoding='UTF-8'))
self.logfile.flush() self.logfile.flush()
if self.logfile_read is not None: if self.logfile_read is not None:
self.logfile_read.write (s) self.logfile_read.write (s.decode(encoding='UTF-8'))
self.logfile_read.flush() self.logfile_read.flush()
return s return s
@ -950,7 +950,7 @@ class spawn (object):
if self.logfile_send is not None: if self.logfile_send is not None:
self.logfile_send.write (s) self.logfile_send.write (s)
self.logfile_send.flush() self.logfile_send.flush()
c = os.write(self.child_fd, s) c = os.write(self.child_fd, s.encode(encoding='UTF-8'))
return c return c
def sendline(self, s=''): def sendline(self, s=''):
@ -1071,7 +1071,7 @@ class spawn (object):
else: else:
return False return False
return False return False
except OSError, e: except OSError as e:
# I think there are kernel timing issues that sometimes cause # I think there are kernel timing issues that sometimes cause
# this to happen. I think isalive() reports True, but the # this to happen. I think isalive() reports True, but the
# process is dead to the kernel. # process is dead to the kernel.
@ -1130,7 +1130,7 @@ class spawn (object):
try: try:
pid, status = os.waitpid(self.pid, waitpid_options) pid, status = os.waitpid(self.pid, waitpid_options)
except OSError, e: # No child processes except OSError as e: # No child processes
if e[0] == errno.ECHILD: if e[0] == errno.ECHILD:
raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?')
else: else:
@ -1142,7 +1142,7 @@ class spawn (object):
if pid == 0: if pid == 0:
try: try:
pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris! pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris!
except OSError, e: # This should never happen... except OSError as e: # This should never happen...
if e[0] == errno.ECHILD: if e[0] == errno.ECHILD:
raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?')
else: else:
@ -1209,7 +1209,7 @@ class spawn (object):
if patterns is None: if patterns is None:
return [] return []
if type(patterns) is not types.ListType: if type(patterns) is not list:
patterns = [patterns] patterns = [patterns]
compile_flags = re.DOTALL # Allow dot to match \n compile_flags = re.DOTALL # Allow dot to match \n
@ -1217,7 +1217,7 @@ class spawn (object):
compile_flags = compile_flags | re.IGNORECASE compile_flags = compile_flags | re.IGNORECASE
compiled_pattern_list = [] compiled_pattern_list = []
for p in patterns: for p in patterns:
if type(p) in types.StringTypes: if type(p) in (str,bytes):
compiled_pattern_list.append(re.compile(p, compile_flags)) compiled_pattern_list.append(re.compile(p, compile_flags))
elif p is EOF: elif p is EOF:
compiled_pattern_list.append(EOF) compiled_pattern_list.append(EOF)
@ -1372,16 +1372,16 @@ class spawn (object):
self.match_index = index self.match_index = index
return self.match_index return self.match_index
# No match at this point # No match at this point
if timeout < 0 and timeout is not None: if timeout is not None and timeout < 0:
raise TIMEOUT ('Timeout exceeded in expect_any().') raise TIMEOUT ('Timeout exceeded in expect_any().')
# Still have time left, so read more data # Still have time left, so read more data
c = self.read_nonblocking (self.maxread, timeout) c = self.read_nonblocking (self.maxread, timeout)
freshlen = len(c) freshlen = len(c)
time.sleep (0.0001) time.sleep (0.0001)
incoming = incoming + c incoming = incoming + c.decode(encoding='UTF-8')
if timeout is not None: if timeout is not None:
timeout = end_time - time.time() timeout = end_time - time.time()
except EOF, e: except EOF as e:
self.buffer = '' self.buffer = ''
self.before = incoming self.before = incoming
self.after = EOF self.after = EOF
@ -1394,7 +1394,7 @@ class spawn (object):
self.match = None self.match = None
self.match_index = None self.match_index = None
raise EOF (str(e) + '\n' + str(self)) raise EOF (str(e) + '\n' + str(self))
except TIMEOUT, e: except TIMEOUT as e:
self.buffer = incoming self.buffer = incoming
self.before = incoming self.before = incoming
self.after = TIMEOUT self.after = TIMEOUT
@ -1419,7 +1419,7 @@ class spawn (object):
"""This returns the terminal window size of the child tty. The return """This returns the terminal window size of the child tty. The return
value is a tuple of (rows, cols). """ value is a tuple of (rows, cols). """
TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912L) TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912)
s = struct.pack('HHHH', 0, 0, 0, 0) s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s) x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s)
return struct.unpack('HHHH', x)[0:2] return struct.unpack('HHHH', x)[0:2]
@ -1441,7 +1441,7 @@ class spawn (object):
# Newer versions of Linux have totally different values for TIOCSWINSZ. # Newer versions of Linux have totally different values for TIOCSWINSZ.
# Note that this fix is a hack. # Note that this fix is a hack.
TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561)
if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. if TIOCSWINSZ == 2148037735: # L is not required in Python >= 2.2.
TIOCSWINSZ = -2146929561 # Same bits, but with sign. TIOCSWINSZ = -2146929561 # Same bits, but with sign.
# Note, assume ws_xpixel and ws_ypixel are zero. # Note, assume ws_xpixel and ws_ypixel are zero.
s = struct.pack('HHHH', r, c, 0, 0) s = struct.pack('HHHH', r, c, 0, 0)
@ -1547,7 +1547,7 @@ class spawn (object):
while True: while True:
try: try:
return select.select (iwtd, owtd, ewtd, timeout) return select.select (iwtd, owtd, ewtd, timeout)
except select.error, e: except select.error as e:
if e[0] == errno.EINTR: if e[0] == errno.EINTR:
# if we loop back we have to subtract the amount of time we already waited. # if we loop back we have to subtract the amount of time we already waited.
if timeout is not None: if timeout is not None:

View file

@ -647,7 +647,7 @@ class TargetAndroid(Target):
self.buildozer.error('Invalid library reference (path not found): {}'.format(cref)) self.buildozer.error('Invalid library reference (path not found): {}'.format(cref))
exit(1) exit(1)
# get a relative path from the project file # get a relative path from the project file
ref = relpath(ref, dist_dir) ref = relpath(ref, realpath(dist_dir))
# ensure the reference exists # ensure the reference exists
references.append(ref) references.append(ref)

View file

@ -1,7 +1,7 @@
Specifications Specifications
============== ==============
This document explain in details all the configuration token you can use in This document explains in detail all the configuration tokens you can use in
`buildozer.spec`. `buildozer.spec`.
Section [app] Section [app]
@ -9,9 +9,10 @@ Section [app]
- `title`: String, title of your application. - `title`: String, title of your application.
It might possible that some characters are not working depending the paltform It might be possible that some characters are not working depending on the
targetted. Best for you is to try and see. Try to avoid too-long title, as targeted paltform. It's best to try and see if everything works as expected.
they will also not fit in the title displayed under the icon. Try to avoid too long titles, as they will also not fit in the title
displayed under the icon.
- `package.name`: String, package name. - `package.name`: String, package name.
@ -21,40 +22,40 @@ Section [app]
- `package.domain`: String, package domain. - `package.domain`: String, package domain.
Package domain is a string that reference the company or individual that did Package domain is a string that references the company or individual that
it. Both domain+name will become your application identifier for Android and did the app. Both domain+name will become your application identifier for
iOS. Choose it carefully. As an example, when the Kivy`s team is publishing Android and iOS, choose it carefully. As an example, when the Kivy`s team
an application, the domain starts with `org.kivy`. is publishing an application, the domain starts with `org.kivy`.
- `source.dir`: String, location of your application sources. - `source.dir`: String, location of your application sources.
The location must be a directory that contain a `main.py` file. It defaults The location must be a directory that contains a `main.py` file. It defaults
to the same directory as the one `buildozer.spec` is. to the directory where `buildozer.spec` is.
- `source.include_exts`: List, files extensions to include. - `source.include_exts`: List, files' extensions to include.
By default, not all the file in your `source.dir` are included, but only some By default, not all files in your `source.dir` are included, but only some
of them, depending the extension. Ie, we includes `py,png,jpg,kv,atlas`. Feel of them (`py,png,jpg,kv,atlas`), depending on the extension. Feel free to
free to add your own extensions, or put an empty value if you want to include add your own extensions, or use an empty value if you want to include
everything. everything.
- `source.exclude_exts`: List, files extensions to exclude. - `source.exclude_exts`: List, files' extensions to exclude.
In contrary to `source.include_exts`, you could include all the files you In contrary to `source.include_exts`, you could include all the files you
want except the one that ends with an extension contain in this token. If want except the ones that end with an extension listed in this token. If
empty, no files will be excluded by the extensions. empty, no files will be excluded based on their extensions.
- `source.exclude_dirs`: List, directories to exclude. - `source.exclude_dirs`: List, directories to exclude.
Same as `source.exclude_exts`, but for directory. You can exclude your Same as `source.exclude_exts`, but for directories. You can exclude your
`tests` or `bin` directory with:: `tests` and `bin` directory with::
source.exclude_dirs = tests, bin source.exclude_dirs = tests, bin
- `source.exclude_patterns`: List, file to exclude if they match a pattern. - `source.exclude_patterns`: List, files to exclude if they match a pattern.
If you have a more complex application layout, you might need a pattern to If you have a more complex application layout, you might need a pattern to
exclude files. It works also even if you don't have a pattern. For example:: exclude files. It also works if you don't have a pattern. For example::
source.exclude_patterns = license,images/originals/* source.exclude_patterns = license,images/originals/*
@ -62,54 +63,54 @@ Section [app]
`version.filename`. `version.filename`.
The default capture method of your application version is by grepping a line The default capture method of your application version is by grepping a line
like that:: like this::
__version__ = "1.0" __version__ = "1.0"
The `1.0` will be used as a version. The `1.0` will be used as a version.
- `version.filename`: String, default to the main.py. - `version.filename`: String, defaults to the main.py.
Filename to use for capturing the version with `version.regex`. File to use for capturing the version with `version.regex`.
- `version`: String, manual application version. - `version`: String, manual application version.
If you don't want to capture the version, comment both of `version.regex` and If you don't want to capture the version, comment out both `version.regex`
`version.filename`, then put the version you want directly in the `version` and `version.filename`, then put the version you want directly in the
token:: `version` token::
# version.regex = # version.regex =
# version.filename = # version.filename =
version = 1.0 version = 1.0
- `requirements`: List, Python module or extensions that your application - `requirements`: List, Python modules or extensions that your application
require. requires.
The requirements can be either a name of a recipe in the Python-for-android The requirements can be either a name of a recipe in the Python-for-android
project, or a pure-Python package. For example, if your application require project, or a pure-Python package. For example, if your application requires
Kivy and requests, you need to write:: Kivy and requests, you need to write::
requirements = kivy,requests requirements = kivy,requests
If your application try to install a Python extension (ie, a Python package If your application tries to install a Python extension (ie, a Python
that require compilation), and that it doesn't have a recipe associated to package that requires compilation), and the extension doesn't have a recipe
Python-for-android, it will not work. We explicitely disable the compilation associated to Python-for-android, it will not work. We explicitly disable
here. If you want to make it work, contribute to the Python-for-android the compilation here. If you want to make it work, contribute to the
project by creating a recipe. See :doc:`contribute` Python-for-android project by creating a recipe. See :doc:`contribute`.
- `garden_requirements`: List, Garden packages to include. - `garden_requirements`: List, Garden packages to include.
Add here the list of Kivy's garden package to include. For example:: Add here the list of Kivy's garden packages to include. For example::
garder_requirements = graph garden_requirements = graph
Please note that if it doesn't work, it might be because of the garden Please note that if it doesn't work, it might be because of the garden
package itself. Refer to the author of the package if he already tested it on package itself. Refer to the author of the package if he already tested
the platform you are targetting, not us. it on your target platform, not us.
- `presplash.filename`: String, loading screen of your application. - `presplash.filename`: String, loading screen of your application.
Presplash is the image showed on the device when the application is loading. Presplash is the image shown on the device during application loading.
It is called presplash on Android, and Loading image on iOS. The image might It is called presplash on Android, and Loading image on iOS. The image might
have different requirements depending the platform. Currently, Buildozer have different requirements depending the platform. Currently, Buildozer
works well only with Android, iOS support is not great on this. works well only with Android, iOS support is not great on this.
@ -126,12 +127,12 @@ Section [app]
- `orientation`: String, orientation of the application. - `orientation`: String, orientation of the application.
Indicate the orientation that your application support. Defaults to Indicate the orientation that your application supports. Defaults to
`landscape`, but can be changed to `portrait` or `all`. `landscape`, but can be changed to `portrait` or `all`.
- `fullscreen`: Boolean, fullscreen mode. - `fullscreen`: Boolean, fullscreen mode.
Defaults to true, your application will run in fullscreen. Means the status Defaults to true, your application will run in fullscreen. Means the status
bar will be hidden. If you want to let the user access to the status bar, bar will be hidden. If you want to let the user access the status bar,
hour, notifications, put to 0. hour, notifications, use 0 as a value.