Hi,

I've got a bit of experience on frescobaldi builds. I have started doing a .app 
bundle for Mac, but never succeeded and I am slow because of the low available 
time for this project.

So if you want to continue upon what I have discovered, I'll switch to more 
technical matter. (I'm CCing this message to lilypond-user, but I think it 
would be appropriate for the frescobaldi list)

For macports, the only package missing before frescobaldi if py-poppler.

I have a frozen folder here that works and even results in frescobaldi using 
the retina display (texts only but it's a great enhancement). I have played 
with the setup and freeze scripts.

cx_freeze now have a bdist_mac target, which would result in a .app bundle.
cx_freeze installed from macports is too old to have this target, so I had to 
modify the port file to get the last version. I'll send it to macports.

Just modifying the script setup.py does not create a working .app. cx_freeze 
must have missed some dependencies, I don't know which ones.
Modifying the freeze.py to remove windows specific things does create a folder 
with apparently everything needed (and even some things not needed). But from 
there I don't know how to invoke cx_freeze to create a bundle.

Jean-Alexis

#! python

# This script freezes Frescobaldi to a standalone application without
# needing to install any dependencies.
#
# Usage:
# C:\Python27\Python freeze.py
#
# How it works:
# It creates, using cx_Freeze, a frescobaldi executable inside the frozen/
# directory, along with all used (manually specified) Python modules.
# Then the whole frescobaldi_app directory is copied and the Python scripts
# byte-compiled.
# Finally, an installer is created using the Inno Setup console-mode compiler.

# the Inno Setup console-mode compiler
iscc = 'c:\\Program Files\\Inno Setup 5\\ISCC'

# where to build the frozen program folder
target_dir = 'frozen'

# import standard modules and cx_Freeze
import imp
import os
import py_compile
import shutil
import subprocess
import sys
from cx_Freeze import Executable, Freezer

# access meta-information such as version, etc.
from frescobaldi_app import info

# find pypm by adding the dir of pygame to sys.path
sys.path.append(imp.find_module('pygame')[1])

includes = [
    'sip',
    'PyQt4.QtCore',
    'PyQt4.QtGui',
    'PyQt4.QtWebKit',
    'PyQt4.QtNetwork',
    'PyQt4.QtSvg',
    'PyQt4.QtXml',
    'popplerqt4',
    'pypm',
    
    '__future__',
    'bisect',
    'contextlib',
    'difflib',
    'fractions',
    'glob',
    'json',
    'itertools',
    'functools',
    'optparse',
    'os',
    'platform',
    're',
    'sys',
    'shutil',
    'struct',
    'subprocess',
    'traceback',
    'types',
    'unicodedata',
    'weakref',
    'xml.etree.ElementTree',
]

excludes = [
    'frescobaldi_app',  # we'll add this one manually
    
]

frescobaldi = Executable(
    'frescobaldi',
#    icon = 'frescobaldi_app/icons/frescobaldi.ico',
    appendScriptToExe = True,
#    base = 'Win32GUI', # no console
)

f = Freezer(
    [frescobaldi],
    includes = includes,
    excludes = excludes,
    targetDir = target_dir,
    copyDependentFiles = True,
    compress = False,
    # silent = True,
)

f.Freeze()

def copy_plugins(name):
    """Copies a folder from the Qt4 plugins directory."""
    path = imp.find_module('PyQt4')[1]
    # folder = os.path.join(path, 'plugins', name)
    folder = '/opt/local/share/qt4/plugins'
    target = os.path.join(target_dir, name)
    shutil.rmtree(target, ignore_errors = True)
    shutil.copytree(folder, target)

# copy Qt4 imageformat plugins
copy_plugins('imageformats')

# copy Qt4 iconengine plugins
copy_plugins('iconengines')

# copy the frescobaldi_app directory
subprocess.call([sys.executable, 'setup.py', 'build_py',
	'--build-lib', target_dir, '--compile'])

# make an Inno Setup installer
inno_script = b'''
[Setup]
AppName=Frescobaldi
AppVersion={version}
AppVerName=Frescobaldi {version}
AppPublisher={author}
AppPublisherURL={homepage}
AppComments={comments}

DefaultDirName={{pf}}\\Frescobaldi
DefaultGroupName=Frescobaldi
UninstallDisplayIcon={{app}}\\frescobaldi.exe
Compression=lzma2
SolidCompression=yes

SourceDir={target}\\
OutputDir=..\\dist\\
OutputBaseFilename="Frescobaldi Setup {version}"
SetupIconFile=frescobaldi_app\\icons\\frescobaldi.ico
LicenseFile=..\\COPYING
WizardImageFile=..\\frescobaldi-wininst.bmp
WizardImageStretch=no

[Files]
Source: "*.*"; DestDir: "{{app}}"; Flags: recursesubdirs;

[Icons]
Name: "{{group}}\Frescobaldi"; Filename: "{{app}}\\frescobaldi.exe";

[Tasks]
Name: assocly; Description: "{{cm:AssocFileExtension,Frescobaldi,.ly}}";

[Registry]
Root: HKCR; Subkey: "LilyPond\\shell\\frescobaldi";\
 ValueType: string; ValueName: ""; ValueData: "Edit with &Frescobaldi...";\
 Flags: uninsdeletekey
Root: HKCR; Subkey: "LilyPond\\shell\\frescobaldi\\command";\
 ValueType: string; ValueName: ""; ValueData: """{{app}}\\frescobaldi.exe"" ""%1"""
Tasks: assocly; Root: HKCR; Subkey: "LilyPond\\shell";\
 ValueType: string; ValueName: ""; ValueData: "frescobaldi";

[Run]
Filename: "{{app}}\\frescobaldi.exe";\
 Description: {{cm:LaunchProgram,Frescobaldi}};\
 Flags: postinstall nowait skipifsilent;

'''.format(
    version=info.version,
    homepage=info.url,
    author=info.maintainer,
    comments=info.description,
    target=target_dir,
)

subprocess.Popen([iscc, '-'], stdin=subprocess.PIPE).communicate(inno_script)

import os
import sys
from cx_Freeze import setup, Executable
from frescobaldi_app import info

def packagelist(directory):
    """Returns a sorted list with package names for all packages under the given directory."""
    return list(sorted(root.replace(os.sep, '.')
        for root, dirs, files in os.walk(directory)
        if '__init__.py' in files))

scripts = ['frescobaldi']
packages = packagelist('frescobaldi_app')
print packages;
package_data = {
    'frescobaldi_app.css': ['*.png'],
    'frescobaldi_app.help': ['*.png'],
    'frescobaldi_app.hyphdicts': ['*.dic'],
    'frescobaldi_app.icons': [
        '*.ico',
        '*.svg',
        '*x*/*.png',
        'Tango/index.theme',
        'Tango/scalable/*.svg',
        'TangoExt/index.theme',
        'TangoExt/scalable/*.svg',
    ],
    'frescobaldi_app.po': ['*.mo'],
    'frescobaldi_app.scorewiz': ['*.png'],
    'frescobaldi_app.splashscreen': ['*.png'],
    'frescobaldi_app.symbols': ['*.svg'],
}

if sys.platform.startswith('win'):
    scripts.append('frescobaldi-wininst.py')
    data_files = []
else:
    data_files = [
        ('share/icons/hicolor/scalable/apps', ['frescobaldi_app/icons/frescobaldi.svg']),
        ('share/applications', ['frescobaldi.desktop']),
    ]

classifiers = [
    'Development Status :: 5 - Production/Stable',
    'Environment :: MacOS X',
    'Environment :: Win32 (MS Windows)',
    'Environment :: X11 Applications :: Qt',
    'Intended Audience :: End Users/Desktop',
    'License :: OSI Approved :: GNU General Public License (GPL)',
    'Natural Language :: Czech',
    'Natural Language :: Dutch',
    'Natural Language :: English',
    'Natural Language :: French',
    'Natural Language :: Galician',
    'Natural Language :: German',
    'Natural Language :: Italian',
    'Natural Language :: Polish',
    'Natural Language :: Portuguese (Brazilian)',
    'Natural Language :: Russian',
    'Natural Language :: Spanish',
    'Natural Language :: Turkish',
    'Natural Language :: Ukranian',
    'Operating System :: MacOS :: MacOS X',
    'Operating System :: Microsoft :: Windows',
    'Operating System :: POSIX',
    'Programming Language :: Python :: 2.6',
    'Programming Language :: Python :: 2.7',
    'Topic :: Multimedia :: Sound/Audio',
    'Topic :: Multimedia :: Graphics',
    'Topic :: Text Editors',
]

setup(
    name = info.name,
    version = info.version,
    description = info.description,
    long_description = info.long_description,
    maintainer = info.maintainer,
    maintainer_email = info.maintainer_email,
    url = info.url,
    license = info.license,
    
    scripts = scripts,
    packages = packages,
    package_data = package_data,
    data_files = data_files,
    classifiers = classifiers,
    executables = [Executable("frescobaldi_main.py", base=None)]
)

On 6 juin 2013, at 17:03, Wilbert Berendsen <i...@wilbertberendsen.nl> wrote:

> Op 06-06-13 12:35, Andrew Bernard schreef:
>> As a result of this thread, I have decided the need is there for a macports 
>> bundle for frescobaldi, one that includes all the dependencies with no 
>> headaches. This seems to be what people want, short of a Mac GUI installed. 
>> I'll start in on that project tomorrow.
> That'd be great!
> 
> Like I wrote earlier: I built such an installer for Windows (because I have 
> Windows on my small laptop, besides Linux) using cx_Freeze. The script is 
> freeze.py. You could look at the setup scripts for other PyQt4 apps that 
> include a Mac OS X installer with all dependencies contained, e.g. by 
> searching GitHub for 'py2app' in code, etc.
> 
> If you could create build script that builds an installer, it can simply be 
> run to create a Mac OS installer for every release. I'd be happy to have it 
> in the download section then!
> 
> Thanks for all the efforts!
> 
> Best wishes,
> Wilbert (Fresc. dev).
> 
> -- 
> Wilbert Berendsen
> http://www.wilbertberendsen.nl/
> 
> 
> _______________________________________________
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to