summaryrefslogtreecommitdiffstats
path: root/src/SConscript
diff options
context:
space:
mode:
Diffstat (limited to 'src/SConscript')
-rw-r--r--src/SConscript810
1 files changed, 810 insertions, 0 deletions
diff --git a/src/SConscript b/src/SConscript
new file mode 100644
index 0000000000..514609c518
--- /dev/null
+++ b/src/SConscript
@@ -0,0 +1,810 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os
+import sys
+import SCons
+import shutil
+import subprocess
+import time
+import SCons.Script as SCons
+
+from build import util, depends
+
+mixxx_version = util.get_mixxx_version()
+branch_name = util.get_branch_name()
+vcs_revision = util.get_revision()
+vcs_name = util.get_current_vcs()
+print "WE ARE IN:", os.getcwd()
+print "Building ", branch_name, " - rev.", vcs_revision
+
+plugins = []
+
+# Grab these from the SConstruct above us
+Import('build')
+Import('sources')
+Import('soundsource_plugins')
+Import('mixxxminimal_plugins')
+
+env = build.env
+flags = build.flags
+
+#Tell SCons to build Mixxx
+#=========================
+if build.platform_is_windows:
+ dist_dir = 'dist%s' % build.bitwidth
+ # Populate the stuff that changes in the .rc file
+ fo = open(File('#src/mixxx.rc.include').abspath, "w")
+
+ str_list = []
+ str_list.append('#define VER_FILEVERSION ')
+ # Remove anything after ~ or - in the version number and replace the dots with commas
+ str_list.append(mixxx_version.partition('~')[0].partition('-')[0].replace('.',','))
+ str_list.append(','+str(vcs_revision)+'\n')
+
+ str_list.append('#define VER_PRODUCTVERSION ')
+ str_list.append(mixxx_version.partition('~')[0].partition('-')[0].replace('.',','))
+ str_list.append(','+str(vcs_revision)+'\n')
+
+ import datetime
+ now = datetime.datetime.now()
+ str_list.append('#define CUR_YEAR "'+str(now.year)+'"\n\n')
+
+ if build.msvcdebug:
+ str_list.append('#define DEBUG 1\n')
+ if 'pre' in mixxx_version.lower():
+ str_list.append('#define PRERELEASE 1\n')
+
+ fo.write(''.join(str_list))
+ fo.close()
+
+ mixxx_bin = env.Program('mixxx',
+ [sources, env.RES('#src/mixxx.rc')],
+ LINKCOM = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1'])
+else:
+ mixxx_bin = env.Program('mixxx', sources)
+
+def build_tests():
+ test_files = Glob('test/*.cpp', strings=True)
+ test_env = env.Clone()
+ test_env.Append(CPPPATH="#lib/gtest-1.5.0/include")
+ test_env.Append(CPPPATH="#lib/gmock-1.5.0/include")
+ test_files = [test_env.StaticObject(filename) \
+ if filename !='main.cpp' else filename
+ for filename in test_files]
+ mixxx_sources = [filename for filename in sources if filename != 'main.cpp']
+ test_sources = (test_files + mixxx_sources)
+
+ env.Append(LIBPATH="#lib/gtest-1.5.0/lib")
+ env.Append(LIBS = 'gtest')
+
+ env.Append(LIBPATH="#lib/gmock-1.5.0/lib")
+ env.Append(LIBS = 'gmock')
+
+ env.Program(target='mixxx-test', source=test_sources)
+
+ Command("../mixxx-test", "./mixxx-test", Copy("$TARGET", "$SOURCE"))
+
+def run_tests():
+ ret = Execute("./mixxx-test")
+ if ret != 0:
+ print "WARNING: Not all tests pass. See mixxx-test output."
+ Exit(ret)
+
+if int(build.flags['test']):
+ print "Building tests."
+ build_tests()
+
+if 'test' in BUILD_TARGETS:
+ print "Running tests."
+ run_tests()
+
+def osx_construct_version(build, mixxx_version, branch_name, vcs_revision):
+ # In release mode, we only use the version.
+ if build.build_is_release:
+ return mixxx_version
+ elif branch_name.startswith('release-'):
+ return '%s-%s%s' % (mixxx_version, vcs_name, vcs_revision)
+ # In a debug build, include the branch name and revision number
+ return "%s-%s-%s%s" % (mixxx_version, branch_name, vcs_name, vcs_revision)
+
+def ubuntu_construct_version(build, mixxx_version, branch_name, vcs_revision,
+ ubuntu_version):
+ # Underscores are not ok in version names, dashes are fine though.
+ if branch_name:
+ branch_name = branch_name.replace('_', '-')
+ # In release mode, we only use the version and ubuntu_version
+ if build.build_is_release:
+ return "%s-%s" % (mixxx_version, ubuntu_version)
+ elif branch_name.startswith('release-'):
+ return "%s-%s%s" % (mixxx_version, vcs_name, vcs_revision)
+ # In a debug build, include the branch name and revision number
+ return "%s-%s~%s~%s%s" % (mixxx_version, ubuntu_version,
+ branch_name, vcs_name, vcs_revision)
+
+def windows_construct_version(build, mixxx_version, branch_name, vcs_revision):
+ # In release mode, we only use the version
+ if build.build_is_release:
+ return mixxx_version
+ elif branch_name.startswith('release-'):
+ return '%s-%s%s' % (mixxx_version, vcs_name, vcs_revision)
+ # In a debug build, include the branch name and revision number
+ return "%s-%s-%s%s" % (mixxx_version, branch_name, vcs_name, vcs_revision)
+
+#Set up the install target
+#=========================
+
+# flags['prefix'] = ARGUMENTS.get('prefix', '/usr/local')
+# if not os.path.exists(flags['prefix']):
+# print "Error: Prefix path does not exist!"
+# Exit(1)
+# else:
+# unix_share_path = flags['prefix'] + "/share"
+# unix_bin_path = flags['prefix'] + "/bin"
+
+#Mixxx binary
+binary_files = mixxx_bin;
+
+# Mixxx essential resource files
+resource_files = Glob('#res/schema.xml')
+
+#Soundsource plugins
+soundsource_plugin_files = soundsource_plugins
+
+#VAMP beat tracking and key detection plugin
+libmixxxminimal_vamp_plugin = mixxxminimal_plugins
+
+#Skins
+skin_files = Glob('#res/skins/*')
+
+#Controller mappings
+controllermappings_files = Glob('#res/controllers/*')
+
+# Translation files
+translation_files = Glob('#res/translations/*.qm')
+
+#Keyboard mapping(s)
+keyboardmappings_files = Glob('#res/keyboard/*')
+
+#Promo tracks
+promotracks_files = Glob('#res/promo/*')
+
+#LADSPA shizzle
+ladspapresets_files = Glob('#res/ladspa_presets/*')
+
+#Documentation
+docs_files = Glob('#./LICENSE')
+docs_files += Glob('#./README')
+docs_files += Glob('#./Mixxx-Manual.pdf')
+
+#.desktop file for KDE/GNOME menu
+dotdesktop_files = Glob('#src/mixxx.desktop')
+
+#Icon file for menu entry
+icon_files = Glob('#res/images/mixxx-icon.png')
+
+#Images for preferences dialog
+image_files = Glob('#res/images/preferences/*') # These are compiled in to the "mixxx" binary through mixxx.qrc
+
+#Windows DLLs
+
+# TODO: Use reference to SharedLibrary for libsndfile and others, glob only gets
+# all files on 2+ builds after a clean.
+if build.toolchain_is_msvs:
+ mixxx_winlib_path = SCons.ARGUMENTS.get('winlib', '..\\..\\..\\mixxx-win32lib-msvc90-release')
+ # skip the MSVC DLLs incase they're in there too
+ dll_files = Glob('%s/[!"msvc"]*.dll' % mixxx_winlib_path)
+elif build.crosscompile and build.platform_is_windows and build.toolchain_is_gnu:
+ # We're cross-compiling, grab these from the crosscompile bin
+ # folder. How should we be doing this?
+ dll_files = Glob('#/../../mixxx-win%slib-crossmingw' % build.bitwidth)
+elif build.crosscompile and build.platform_is_osx:
+ # Glob appropriate dylib files. We have 4 different library types,
+ # x86_64, x86, powerpc, powerpc64
+ dylib_files = Glob('#/../../mixxx-osx-%s-crossmingw' % build.machine)
+else:
+ dll_files = list() # dll_files += on the next line required dll_files to exist
+
+if build.msvcdebug:
+ dll_files += Split("""$QTDIR/lib/QtWebKitd4.dll""")
+else:
+ dll_files += Split("""$QTDIR/lib/QtWebKit4.dll""")
+
+if build.msvcdebug:
+ dll_files += Split("""$QTDIR/lib/QtCored4.dll
+ $QTDIR/lib/QtGuid4.dll
+ $QTDIR/lib/QtNetworkd4.dll
+ $QTDIR/lib/QtOpenGLd4.dll
+ $QTDIR/lib/QtSqld4.dll
+ $QTDIR/lib/QtXmld4.dll
+ $QTDIR/lib/QtXmlPatternsd4.dll
+ $QTDIR/lib/QtSvgd4.dll
+ $QTDIR/lib/phonond4.dll
+ $QTDIR/lib/QtScriptd4.dll""")
+else:
+ # if not int(build.flags['staticlibs']):
+ dll_files += Split("""$QTDIR/lib/QtCore4.dll
+ $QTDIR/lib/QtGui4.dll
+ $QTDIR/lib/QtNetwork4.dll
+ $QTDIR/lib/QtOpenGL4.dll
+ $QTDIR/lib/QtSql4.dll
+ $QTDIR/lib/QtXml4.dll
+ $QTDIR/lib/QtXmlPatterns4.dll
+ $QTDIR/lib/QtSvg4.dll
+ $QTDIR/lib/phonon4.dll
+ $QTDIR/lib/QtScript4.dll""")
+
+if int(flags.get('sqlitedll', 0)):
+ if build.msvcdebug:
+ sqldll_files = Split("""$QTDIR/plugins/sqldrivers/qsqlited4.dll""") #Qt SQLite plugin
+ else:
+ sqldll_files = Split("""$QTDIR/plugins/sqldrivers/qsqlite4.dll""") #Qt SQLite plugin
+
+if build.platform_is_linux or build.platform_is_bsd:
+ flags['prefix'] = ARGUMENTS.get('prefix', '/usr/local')
+ if not os.path.exists(flags['prefix']):
+ print "Error: Prefix path does not exist!"
+ Exit(1)
+ else:
+ #install_root is used in Debian/Ubuntu packaging (check the debian/rules file in the Ubuntu package)
+ #Basically, the flags['prefix'] is compiled into strings in Mixxx, whereas the install_root is not. When you're
+ #building a Debian package, pbuilder wants to install Mixxx to a temporary directory, but you still need
+ #the compiled-in strings using /usr as the prefix. That's why we have install_root and flags['prefix'].
+ install_root = ARGUMENTS.get('install_root', flags['prefix'])
+ print "Install root: " + install_root
+ unix_share_path = os.path.join(install_root, 'share')
+ unix_bin_path = os.path.join(install_root, 'bin')
+ unix_lib_path = os.path.join(install_root, 'lib')
+
+ binary = env.Install(unix_bin_path, binary_files)
+ resource = env.Install(os.path.join(unix_share_path, 'mixxx'), resource_files)
+ skins = env.Install(os.path.join(unix_share_path, 'mixxx', 'skins'), skin_files)
+ vamp_plugin = env.Install(
+ os.path.join(unix_lib_path, 'mixxx', 'plugins', 'vamp'),
+ libmixxxminimal_vamp_plugin)
+
+ soundsource_plugins = env.Install(
+ os.path.join(unix_lib_path, 'mixxx', 'plugins', 'soundsource'),
+ soundsource_plugin_files)
+ controllermappings = env.Install(os.path.join(unix_share_path, 'mixxx', 'controllers'), controllermappings_files)
+ translations = env.Install(os.path.join(unix_share_path, 'mixxx', 'translations'), translation_files)
+ keyboardmappings = env.Install(os.path.join(unix_share_path, 'mixxx', 'keyboard'), keyboardmappings_files)
+ if int(flags['ladspa']):
+ ladspapresets = env.Install(
+ os.path.join(unix_share_path, 'mixxx', 'ladspa_presets'), ladspapresets_files)
+ dotdesktop = env.Install(os.path.join(unix_share_path, 'applications'), dotdesktop_files)
+ docs = env.Install(os.path.join(unix_share_path, 'doc', 'mixxx'), docs_files)
+ icon = env.Install(os.path.join(unix_share_path, 'pixmaps'), icon_files)
+ promotracks = env.Install(os.path.join(unix_share_path, 'mixxx', 'promo'), promotracks_files)
+
+ #Makes each of those Install builders get fired off when you run "scons install" :)
+ env.Alias('install', binary)
+ env.Alias('install', resource)
+ env.Alias('install', skins)
+ env.Alias('install', soundsource_plugins)
+ env.Alias('install', controllermappings)
+ env.Alias('install', translations)
+ env.Alias('install', keyboardmappings)
+ if int(flags['ladspa']):
+ env.Alias('install', ladspapresets)
+ env.Alias('install', docs)
+ env.Alias('install', dotdesktop)
+ env.Alias('install', icon)
+ env.Alias('install', promotracks)
+ env.Alias('install', vamp_plugin)
+
+ #Delete the old Mixxx installation (because SCONS won't overwrite it)
+ #if 'install' in COMMAND_LINE_TARGETS:
+ #os.system('scons -c install')
+ #Delete(unix_share_path + "/mixxx/skins")
+ #print "Copying skins..."
+ #env.Command(unix_share_path + "/mixxx/skins", skin_files, Copy("$TARGET", "$SOURCE"), source_scanner = DirScanner)
+ #Copy(unix_share_path + "/.ixxx/skins", skin_files)
+ #Delete(unix_bin_path + "mixxx")
+
+ #Delete(unix_share_path + "/mixxx/controllers")
+ #Delete(unix_share_path + "/mixxx/keyboard")
+
+#Build the Mixxx.app bundle
+if build.platform_is_osx and 'bundle' in COMMAND_LINE_TARGETS:
+ #Mixxx build variables
+ VOLNAME="Mixxx" #tmp tmp tmp, it's unclean to pass this into build_dmg this way. perhaps pass it in the env?
+ ARCH = 'ppc' if build.machine in ['powerpc', 'powerpc64'] else 'macintel'
+ ARCH += ("64" if build.machine_is_64bit else "32")
+
+ DMG_ICON="#res/osx/VolumeIcon.icns"
+
+ # this is a BIG HACK to support Qt's plugins (since Qt *requires* that
+ # it's plugins be in specific subdirectories, which OS X doesn't really
+ # play nice with)
+ qt_plugins = ([("iconengines", e) for e in ["libqsvgicon.dylib"]] +
+ [("imageformats", e) for e in ["libqgif.dylib", "libqjpeg.dylib", "libqsvg.dylib"]] +
+ [("sqldrivers", e) for e in ["libqsqlite.dylib"]] +
+ [("accessible", e) for e in ["libqtaccessiblewidgets.dylib"]])
+ #Left out libqmng and libqtiff to save space.
+
+ # Concatenate the SoundSource plugins to our list of plugins (converting
+ # from SCons File nodes to strings)
+ for x in soundsource_plugins:
+ plugins.append(x.get_abspath())
+
+ for x in mixxxminimal_plugins:
+ plugins.append(x.get_abspath())
+
+ resource_map = {}
+ translation_files = Glob('#res/translations/*.qm')
+ for tfile in translation_files:
+ resource_map[str(tfile)] = 'translations'
+
+ qtdir = build.env['QTDIR']
+ qt_frameworks = depends.Qt.find_framework_path(qtdir)
+ if not qt_frameworks:
+ raise Exception('Could not find frameworks in Qt directory: %s' % qtdir)
+ #qt_menu.nib for Cocoa Qt 4.7+
+ menu_nib = os.path.join(qt_frameworks, 'QtGui.framework',
+ 'Resources', 'qt_menu.nib')
+ otool_local_paths = [os.path.expanduser("~/Library/Frameworks"),
+ qt_frameworks,
+ "/Library/Frameworks",
+ "/Network/Library/Frameworks",
+ "/usr/local/lib",
+ "/opt/local/lib",
+ "/sw/local/lib"]
+ otool_system_paths = ["/System/Library/Frameworks",
+ "/Network/Library/Frameworks",
+ "/usr/lib"]
+ mixxx_osxlib_path = SCons.ARGUMENTS.get('osxlib', None)
+ if mixxx_osxlib_path:
+ otool_local_paths = [mixxx_osxlib_path,] + otool_local_paths
+
+ qtplugindir = SCons.ARGUMENTS.get('qtplugindir', None)
+ if not qtplugindir:
+ #qtplugindir = '/Developer/Applications/Qt/'
+ qtplugindir = qtdir
+ sources = [mixxx_bin,
+ '#res/osx/application.icns',
+ Dir('#res/skins/'),
+ File('#res/schema.xml'),
+ Dir('#res/controllers/'),
+ translation_files,
+ Dir('#res/keyboard/'),
+ Dir('#res/ladspa_presets'),
+ Dir('#res/doc/'),
+ Dir('#res/promo/'),
+ Dir(menu_nib),
+ File("#README"),
+ File("#LICENSE")]
+ bundle = env.App(
+ "Mixxx",
+ sources,
+ PLUGINS=plugins, ##XXX test what happens if we don't pass any plugins
+ #Qt plugins ((Qt *NEEDS* its plugins in specific locations or it refuses to find them, however this is clearly awkward to write out like this.. maybe))
+ QT_HACK = [(p_tgt_dir, os.path.join(qtplugindir, "plugins", p_tgt_dir, p)) for p_tgt_dir, p in qt_plugins], #sigh :(
+ STRIP=build.build_is_release,
+ APP_RESOURCES_MAP=resource_map,
+ IDENTIFIER="org.mixxx.mixxx",
+ DISPLAY_NAME="Mixxx",
+ VERSION=mixxx_version,
+ SHORT_VERSION=mixxx_version,
+ COPYRIGHT="Copyright © 2011-2013 Mixxx Development Team", #FIXME: datetime.year()
+ # WARNING(rjryan): If you change this, you must also change it
+ # in the build/osx/product_definition.plist.
+ MINIMUM_OSX_VERSION="10.6.0",
+ CATEGORY="public.app-category.music",
+ OTOOL_LOCAL_PATHS=otool_local_paths,
+ OTOOL_SYSTEM_PATHS=otool_system_paths,
+ FOR_APP_STORE=True,
+ )
+ #env.Default(mixxx_bin) #todo: make the Default() just the program itself *globally* (not just for OS X); bundle should be a separate target
+ env.Alias('bundle', bundle)
+
+ codesign_installer_identity = SCons.ARGUMENTS.get('osx_codesign_installer_identity', None)
+ codesign_application_identity = SCons.ARGUMENTS.get('osx_codesign_application_identity', None)
+ codesign_keychain = SCons.ARGUMENTS.get('osx_codesign_keychain', None)
+ codesign_keychain_password = SCons.ARGUMENTS.get('osx_codesign_keychain_password', None)
+ codesign_entitlements = SCons.ARGUMENTS.get('osx_codesign_entitlements', None)
+ # CodeSign needs to take sources for it source so that there is an input
+ # that changse. Otherwise SCons will think the CodeSign target is up to
+ # date and not run it.
+ codesign = env.CodeSign(
+ 'Mixxx',
+ sources,
+ CODESIGN_INSTALLER_IDENTITY=codesign_installer_identity,
+ CODESIGN_APPLICATION_IDENTITY=codesign_application_identity,
+ CODESIGN_KEYCHAIN=codesign_keychain,
+ CODESIGN_KEYCHAIN_PASSWORD=codesign_keychain_password,
+ CODESIGN_ENTITLEMENTS=codesign_entitlements)
+ env.Alias('sign', codesign)
+
+ package_name = 'mixxx'
+ package_version = osx_construct_version(build, mixxx_version, branch_name, vcs_revision)
+ dmg_name = '%s-%s-%s' % (package_name, package_version, ARCH)
+ dmg = env.Dmg(dmg_name, [bundle, ] + docs_files, VOLNAME=VOLNAME, ICON = DMG_ICON)
+ env.Alias('package', dmg)
+
+if build.platform_is_windows:
+ base_dist_dir = '#' + dist_dir
+ skins = env.Install(os.path.join(base_dist_dir, "skins"), skin_files)
+ resource = env.Install(base_dist_dir+"/", resource_files)
+ controllermappings = env.Install(os.path.join(base_dist_dir, "controllers"), controllermappings_files)
+ translations = env.Install(os.path.join(base_dist_dir, "translations"), translation_files)
+ keyboardmappings = env.Install(os.path.join(base_dist_dir, "keyboard"), keyboardmappings_files)
+ if int(flags['ladspa']):
+ ladspapresets = env.Install(os.path.join(base_dist_dir, "ladspa_presets"), ladspapresets_files)
+ docs = env.Install(os.path.join(base_dist_dir, "doc/"), docs_files)
+ promotracks = env.Install(os.path.join(base_dist_dir, "promo/"), promotracks_files)
+ #icon = env.Install(base_dist_dir+"", icon_files)
+ dlls = env.Install(base_dist_dir+"/", dll_files)
+ soundsource_plugins = env.Install(os.path.join(base_dist_dir, "plugins", "soundsource/"),
+ soundsource_plugin_files)
+ vamp_plugins = env.Install(os.path.join(base_dist_dir, "plugins", "vamp/"),
+ libmixxxminimal_vamp_plugin)
+ binary = env.Install(base_dist_dir+"/", binary_files)
+
+ #Always trigger these install builders when compiling on Windows
+ env.Alias('mixxx', skins)
+ env.Alias('mixxx', resource)
+ env.Alias('mixxx', controllermappings)
+ env.Alias('mixxx', translations)
+ env.Alias('mixxx', keyboardmappings)
+ if int(flags['ladspa']):
+ env.Alias('mixxx', ladspapresets)
+ env.Alias('mixxx', promotracks)
+ env.Alias('mixxx', docs)
+ env.Alias('mixxx', dlls)
+ env.Alias('mixxx', soundsource_plugins)
+ env.Alias('mixxx', vamp_plugins)
+ #env.Alias('mixxx', icon)
+ env.Alias('mixxx', binary)
+
+ # QSQLite DLL
+ if 'sqldll_files' in locals():
+ sql_dlls = env.Install(os.path.join(base_dist_dir, "sqldrivers"), sqldll_files)
+ env.Alias('mixxx', sql_dlls)
+
+def win32_find_program_via_registry(program_name):
+ # Windows registry access to find where program is installed
+ import _winreg
+ hklm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
+ program_location_handle = None
+ try:
+ program_location_handle = _winreg.OpenKey(hklm, "SOFTWARE\\"+program_name, 0, _winreg.KEY_READ)
+ except WindowsError:
+ program_location_handle = None
+
+ if not program_location_handle:
+ try:
+ program_location_handle = _winreg.OpenKey(hklm, "SOFTWARE\\Wow6432Node\\"+program_name, 0, _winreg.KEY_READ)
+ except WindowsError:
+ program_location_handle = None
+
+ program_location = _winreg.QueryValue(program_location_handle, None)
+ if not program_location:
+ try:
+ program_location_tuple = _winreg.QueryValueEx(program_location_handle, "Path")
+ program_location = program_location_tuple[0]
+ except WindowsError:
+ program_location_handle = None
+
+ _winreg.CloseKey(hklm)
+ return program_location
+
+def BuildRelease(target, source, env):
+ print
+ print "==== Mixxx Post-Build Checks ===="
+ print
+ print "You have built version %s" % mixxx_version
+ print
+ if int(flags['msvcdebug']):
+ print "YOU ARE ABOUT TO PACKAGE A DEBUG BUILD!!"
+ print
+ print "Binary has size ",
+ if build.platform_is_windows:
+ os.system('for %I in ('+dist_dir+'\mixxx.exe) do @echo %~zI')
+ else:
+ os.system('ls -lh '+dist_dir+'/mixxx.exe | cut -d \' \' -f 5')
+ print
+ print "Installer file ",
+ package_name = 'mixxx'
+
+ package_version = windows_construct_version(
+ build, mixxx_version, branch_name, vcs_revision)
+ arch = "x64" if build.machine_is_64bit else "x86"
+ exe_name = '%s-%s-%s.exe' % (package_name, package_version, arch)
+ print exe_name
+ print
+ print "Top line of README, check version:"
+ if build.platform_is_windows:
+ os.system('for /l %l in (1,1,1) do @for /f "tokens=1,2* delims=:" %a in (\'findstr /n /r "^" README ^| findstr /r "^%l:"\') do @echo %b')
+ else:
+ os.system('head -n 1 README')
+ print
+ print "Top 2 lines of LICENSE, check version and copyright dates:"
+ if build.platform_is_windows:
+ os.system('for /l %l in (1,1,2) do @for /f "tokens=1,2* delims=:" %a in (\'findstr /n /r "^" LICENSE ^| findstr /r "^%l:"\') do @echo %b')
+ else:
+ os.system('head -n 2 LICENSE')
+ print
+ #if (raw_input("Go ahead and build installer (yes/[no])? ") == "yes"):
+ if True:
+ if build.toolchain_is_msvs:
+ redist_file = 'vcredist_%s.exe' % arch
+ print "Searching for the Visual C++ DLL installer package",redist_file
+
+ # First check one level above the winlib directory
+ redist_path = '%s' % os.path.join(os.path.dirname(mixxx_winlib_path), redist_file)
+ print " ",redist_path,
+ if not os.path.isfile(redist_path):
+ print "not found"
+ # If it's not there, look in the MS SDK directory
+ mssdk_path = util.get_mssdk_path()
+ #print " Detected MS SDK path:", mssdk_path
+ redist_path = '%s' % os.path.join(mssdk_path,'Redist','VC',redist_file)
+ print " ",redist_path,
+ if not os.path.isfile(redist_path):
+ print "not found"
+ raise Exception('Cannot find the Visual C++ DLL installer.')
+
+ print "Extracting needed files..."
+ szip_path = None
+ try:
+ szip_directory = win32_find_program_via_registry("7-Zip")
+ szip_path = '%s' % os.path.join(szip_directory, "7z.exe")
+ except Exception, e:
+ pass
+ if szip_path is None:
+ print "Cannot find 7-Zip. Do you have it installed?"
+ raise Exception('Cannot find 7-Zip. Do you have it installed?')
+ else:
+ output_path = '%s' % os.path.join(mixxx_winlib_path,'VC_redist')
+ args = [szip_path,"x","-y","-ir!vc_red.*","-ir!*.msp",redist_path,"-o"+output_path]
+ print "Executing:", ' '.join(args)
+ proc = subprocess.Popen(args)
+ data, err = proc.communicate()
+ rv = proc.wait()
+ if rv:
+ raise Exception('There was a problem extracting the installer files. See above for details.')
+ print "Now building installation package..."
+ command_flag = None
+ nsis_path = None
+ if not build.crosscompile and build.platform_is_windows:
+ nsis_directory = win32_find_program_via_registry("NSIS")
+ nsis_path = '"%s"' % os.path.join(nsis_directory, "makensis.exe")
+ command_flag = '/'
+ elif build.crosscompile and build.platform_is_windows:
+ nsis_path = 'makensis'
+ command_flag = '-'
+
+ if not nsis_path:
+ print "Cannot find NSIS. Do you have it installed?"
+ else:
+ # Call the NSIS build
+ buildwin64 = "/Dx64=1" if build.machine_is_64bit else ''
+ command = '%(path)s /DPACKAGE_NAME=%(package_name)s /DPRODUCT_VERSION=%(version)s /DQTDIR=%(qtpath)s /DWINLIB_PATH=%(winlibpath)s %(64bit)s build\\nsis\\Mixxx.nsi' % \
+ {'path': nsis_path,
+ 'package_name': exe_name,
+ 'version': mixxx_version,
+ 'qtpath': os.environ['QTDIR'],
+ 'winlibpath': mixxx_winlib_path,
+ '64bit': buildwin64}
+ print "Using command: " + command
+ subprocess.check_call(command)
+ else:
+ print "Aborted building installer"
+
+# Do release things
+versionbld = Builder(action = BuildRelease, suffix = '.foo', src_suffix = '.bar')
+env.Append(BUILDERS = {'BuildRelease' : versionbld})
+
+if 'makerelease' in COMMAND_LINE_TARGETS:
+ makerelease = env.BuildRelease('', binary_files)
+ env.Alias('makerelease', makerelease)
+
+def ubuntu_append_changelog(debian_dir,
+ package_name, package_version,
+ description,
+ distro='karmic',
+ urgency='low',
+ author="Mixxx Buildbot <builds@mixxx.org>"):
+ now_formatted = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
+ new_entry = [
+ "%s (%s) %s; urgency=%s" % (package_name, package_version, distro, urgency),
+ "",
+ description,
+ "",
+ " -- %s %s" % (author, now_formatted),
+ "",
+ ]
+ lines = []
+ with open(os.path.join(debian_dir, 'changelog'), 'r') as changelog:
+ lines = list(changelog)
+ with open(os.path.join(debian_dir, 'changelog'), 'w') as changelog:
+ changelog.writelines(["%s\n" % x for x in new_entry])
+ changelog.writelines(lines)
+
+def ubuntu_cleanup():
+ os.system('rm -rf ubuntu')
+ os.mkdir('ubuntu')
+
+# Build the Ubuntu package
+def BuildUbuntuPackage(target, source, env):
+ global mixxx_version
+ print
+ print "==== Mixxx Post-Build Checks ===="
+ print
+ print "You have built version ", mixxx_version
+ print
+ print
+ print "Top line of README, check version:"
+ os.system('head -n 1 README')
+ print
+ print "Top 2 lines of LICENSE, check version and copyright dates:"
+ os.system('head -n 2 LICENSE')
+ print
+ print "Top line of debian/ubuntu changelog, check version:"
+ os.system('head -n 1 build/debian/changelog')
+ print
+
+ print "Now building DEB package..."
+ print
+
+ arch = 'amd64' if build.machine_is_64bit else 'i386'
+
+ package_target = ARGUMENTS.get('package', None)
+ ubuntu_distros = ARGUMENTS.get('ubuntu_dist', None)
+ if ubuntu_distros is None:
+ print "You did not specify an Ubuntu distribution to target. Specify one with the ubuntu_dist flag."
+ # TODO(XXX) default to their current distro? the .pbuilderrc does this
+ return
+ ubuntu_version = ARGUMENTS.get('ubuntu_version', '0ubuntu1')
+ ubuntu_ppa = ARGUMENTS.get('ubuntu_ppa', None)
+
+ ubuntu_distros = ubuntu_distros.split(',')
+
+ # Big hack for PPA upload. We need LP to believe that our original
+ # package version is always changing otherwise it will reject our orig
+ # source tarball.
+ if ubuntu_ppa is not None:
+ mixxx_version = '%s-%s%s' % (mixxx_version, vcs_name, vcs_revision)
+
+ # Destroy ubuntu/ and create it
+ ubuntu_cleanup()
+
+ package_name = 'mixxx'
+
+ # directory and original tarball need to have the upstream-release
+ # version, NOT the package version. For example:
+ # upstream version: 1.10.0-beta1
+ # package version: 1.10.0-beta1-0ubuntu1~bzr2206
+ # directory name: mixxx-1.10.0-beta1
+ # original tarball: mixxx_1.10.0-beta1.orig.tar.gz
+
+ mixxx_dir = '%s-%s' % (package_name, mixxx_version)
+ # The underscore is super important here to make the deb package work
+ mixxx_tarball = "%s_%s.orig.tar.gz" % (package_name, mixxx_version)
+
+ build_dir = os.path.join('ubuntu', mixxx_dir)
+
+ if os.path.exists(build_dir):
+ print "* Cleaning up %s (cwd: %s)" % (build_dir, os.getcwd())
+ print
+ os.system('rm -rf %s' % build_dir) # be careful.
+
+ # TODO: make a get flags arg to accept a revision which can override this and checkout of a specific SVN rev for the package
+
+ # Export the source folder
+ print "* Exporting source folder from current workspace (%s rev: %s)" % (vcs_name,
+ vcs_revision)
+ print
+ util.export_source('.', build_dir)
+
+ # Copy a patch to be included in the exported build sources (this can also be something like src/SConscript, /build/debian/rules)
+ if os.path.exists('post-export-patch'):
+ print "* Applying post export patch"
+ print
+ os.system('cp --dereference -r post-export-patch/* %s' % build_dir)
+
+ # Write a build.h to the exported directory. Later code looks for a
+ # build.h in the mixxx/ directory and moves it to build.build_dir/
+ # instead of generating.
+ util.write_build_header(os.path.join(build_dir, 'build.h'))
+
+ os.chdir('ubuntu')
+
+ # Tar the source code
+ print "* Tarring source directory to '%s' ... (this can take a couple minutes)" % os.path.join(os.getcwd(), mixxx_tarball)
+ print
+ os.system('rm -f "%s"' % mixxx_tarball) #Remove old tarball
+ os.system('tar --exclude build/debian --exclude=debian --exclude=debian/* -czf "%s" %s' % (mixxx_tarball, mixxx_dir))
+
+ os.chdir(mixxx_dir)
+ # Copy the debian folder from /build/debian to exported source folder root
+ print "* Copying Debian build directory from build/debian to debian (cwd: %s)" % os.getcwd()
+ print
+ os.system('cp -r build/debian .')
+
+ for ubuntu_distro in ubuntu_distros:
+ # if a control.$distro file exists, use it
+ if os.path.exists('debian/control.%s' % ubuntu_distro):
+ os.system('cp debian/control.%s debian/control' % ubuntu_distro)
+ # TODO(rryan) currently can only have version 1 within a distro
+ ubuntu_distro_version = '%s~%s1' % (ubuntu_version, ubuntu_distro)
+ package_version = ubuntu_construct_version(build, mixxx_version,
+ branch_name, vcs_revision,
+ ubuntu_distro_version)
+
+ # Add a changelog record for this package
+ if build.build_is_debug:
+ description = " * Experimental build of branch '%s' at Bazaar revision %s" % (branch_name, vcs_revision)
+ ubuntu_append_changelog('debian', package_name, package_version,
+ description, distro=ubuntu_distro)
+ else:
+ description = " * New upstream release."
+ ubuntu_append_changelog('debian', package_name, package_version,
+ description,
+ distro=ubuntu_distro,
+ author="RJ Ryan <rryan@mixxx.org>")
+
+ # Run pbuilder
+ print "* Starting pbuilder ... (cwd: %s)" % os.getcwd()
+ print
+
+ command = ["ARCH=%s" % arch,
+ "DIST=%s" % ubuntu_distro]
+
+ if package_target == 'source':
+ # TODO(rryan) we have to figure out the key-signing situation
+ # here.
+ command.extend(['debuild', '-S', '-sa'])
+ else:
+ command.extend(['pdebuild'])
+ result = os.system(' '.join(command))
+
+ if package_target == 'source':
+ if result == 0:
+ # TODO(rryan) check it actually succeeded
+ print "* Done! Signed source package is in ubuntu/"
+ print
+ else:
+ print "* Build failed."
+ print
+ else:
+ result_path = "/var/cache/pbuilder/%s-%s/result/" % (ubuntu_distro, arch)
+ result_filename = "%s_%s_%s.deb" % (package_name, package_version, arch)
+ result_file = os.path.join(result_path, result_filename)
+ # Since we might build for multiple distros we need to
+ # insert the distro name into the filename.
+ dest_filename = "%s_%s_%s_%s.deb" % (package_name, package_version, ubuntu_distro, arch)
+ # ubuntu/ is one folder up
+ dest_file = os.path.join('..', dest_filename)
+
+ if result == 0 and os.path.exists(result_file):
+ print "Done! Package and tarballs are in %s" % result_path
+ print "* Found package at '%s'. Copying to ubuntu/" % result_filename
+ print
+ shutil.copyfile(result_file, dest_file)
+ else:
+ print "* Build failed."
+ print
+
+ # print "Signing the .deb changes file..."
+ # os.system('sudo debsign /var/cache/pbuilder/result/*.changes')
+
+ if ubuntu_ppa is not None:
+ # dput this changes file to the PPA
+ dput_command = 'dput %s ../%s_%s_source.changes' % (ubuntu_ppa, package_name, package_version)
+ print "* Uploading package for", ubuntu_distro, "to launchpad:", dput_command
+ os.system(dput_command)
+
+ # Return back to the starting directory, otherwise you'll get a .sconsign.dblite error!
+ os.chdir('../..')
+ print "* Returning to starting working directory ... (cwd: " + os.getcwd() + ")"
+ print
+
+#Build the Ubuntu package if "makeubuntu" was passed as an argument
+versiondebbld = Builder(action = BuildUbuntuPackage) #, suffix = '.foo', src_suffix = '.bar')
+env.Append(BUILDERS = {'BuildUbuntuPackage' : versiondebbld})
+
+if 'makeubuntu' in COMMAND_LINE_TARGETS:
+ makeubuntu = env.BuildUbuntuPackage("blah", "defs_version.h" ) #(binary_files)
+ env.Alias('makeubuntu', makeubuntu)