diff options
author | Be <be@mixxx.org> | 2020-12-14 05:17:19 -0600 |
---|---|---|
committer | Be <be@mixxx.org> | 2020-12-14 05:17:19 -0600 |
commit | dff536b605f2024ca731e521fd765ca7c7f6e224 (patch) | |
tree | 622240b547ca847d9ace22505afb59dea83c001d /SConscript | |
parent | 244674929a7f66d93c168f173754868fdd801ba1 (diff) | |
parent | 13fd25a00ff9bbfb9f0c80ca78ae6c4111b7abdf (diff) |
Merge remote-tracking branch 'upstream/2.3' into main
Diffstat (limited to 'SConscript')
-rw-r--r-- | SConscript | 1157 |
1 files changed, 0 insertions, 1157 deletions
diff --git a/SConscript b/SConscript deleted file mode 100644 index 265043b956..0000000000 --- a/SConscript +++ /dev/null @@ -1,1157 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import print_function -import os -import SCons -import shutil -import subprocess -import time -import datetime -import glob -import uuid -from xml.dom import minidom -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') - -env = build.env -flags = build.flags - -# Make a static library of all Mixxx's sources. This library will be linked into -# both mixxx and mixxx-test. -mixxx_lib = env.StaticLibrary('libmixxx', - [source for source in sources - if str(source) != 'src/main.cpp']) -# mixxx.qrc must not be bundled into libmixxx.a since the linker will not link -# it into the resulting binary unless it is on the link command-line explicitly -# (it has no link-time symbols that are needed by anything in Mixxx). -mixxx_qrc = env.StaticObject(env.Qrc5('res/mixxx.cc', 'res/mixxx.qrc')) -# libmixxx.a needs to precede all other libraries so that symbols it requires -# end up in the linker's list of unresolved symbols before other libraries are -# searched for symbols. -env.Prepend(LIBS=mixxx_lib) -mixxx_main = env.StaticObject('src/main.cpp') - -#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('.',',')) - if vcs_revision: - str_list.append(','+str(vcs_revision)) - str_list.append('\n') - - str_list.append('#define VER_PRODUCTVERSION ') - str_list.append(mixxx_version.partition('~')[0].partition('-')[0].replace('.',',')) - if vcs_revision: - str_list.append(','+str(vcs_revision)) - str_list.append('\n') - - import datetime - now = datetime.datetime.now() - str_list.append('#define CUR_YEAR "'+str(now.year)+'"\n\n') - - if build.build_is_debug: - 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_rc = env.RES('src/mixxx.rc') - mixxx_bin = env.Program('mixxx', - [mixxx_main, mixxx_qrc, mixxx_rc], - LINKCOM = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1']) -elif build.platform_is_osx: - # Bug #1258435: executable name must match CFBundleExecutable in the - # Info.plist. For codesigned bundles it seems the CFBundleExecutable - # must match the bundle name or else we SIGILL at startup (not sure - # why). - mixxx_bin = env.Program('Mixxx', [mixxx_main, mixxx_qrc]) -else: - mixxx_bin = env.Program('mixxx', [mixxx_main, mixxx_qrc]) - -# For convenience, copy the Mixxx binary out of the build directory to the -# root. Don't do it on windows because the binary can't run on its own and needs -# the DLLs present with it. -if not build.platform_is_windows: - copy_mixxx_bin = Command("../mixxx", mixxx_bin, Copy("$TARGET", "$SOURCE")) - Default(copy_mixxx_bin) -else: - Default(mixxx_bin) - -test_bin = None -def define_test_targets(default=False): - global test_bin - test_files = Glob('src/test/*.cpp', strings=True) - test_env = env.Clone() - - test_env.Append(CPPPATH="lib/googletest-1.8.x/googletest/include") - test_env.Append(LIBPATH="lib/googletest-1.8.x/googletest") - test_env.Append(LIBS=['gtest']) - - test_env.Append(CPPPATH="lib/googletest-1.8.x/googlemock/include") - test_env.Append(LIBPATH="lib/googletest-1.8.x/googlemock") - test_env.Append(LIBS=['gmock']) - - test_env.Append(CPPPATH="lib/benchmark/include") - test_env.Append(LIBPATH="lib/benchmark") - test_env.Append(LIBS=['benchmark']) - - test_files = [test_env.StaticObject(filename) - if filename !='src/test/main.cpp' else filename - for filename in test_files] - - if build.platform_is_windows: - # For SHGetValueA in Google's benchmark library. - test_env.Append(LIBS=['Shlwapi']) - - # We want a terminal for tests. - if build.toolchain_is_msvs: - test_env['LINKFLAGS'].remove('/subsystem:windows,6.01') - test_env['LINKFLAGS'].append('/subsystem:console,6.01') - elif build.toolchain_is_gnu: - test_env['LINKFLAGS'].remove('--subsystem,windows') - test_env['LINKFLAGS'].append('--subsystem,console') - - # Currently both executables are built with /subsystem:windows - # and the console is attached manually - test_bin = test_env.Program( - 'mixxx-test', [test_files, mixxx_qrc, mixxx_rc], - LINKCOM = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1']) - else: - test_bin = test_env.Program('mixxx-test', [test_files, mixxx_qrc]) - - if not build.platform_is_windows: - copy_test_bin = Command("../mixxx-test", test_bin, Copy("$TARGET", "$SOURCE")) - env.Alias('mixxx-test', copy_test_bin) - # Running mixxx-test via a Command is hacky because it expects a - # target. Using the source '../mixxx-test' makes the Command - # depend on the Copy. - run_test = Command('mixxx-test-results', '../mixxx-test', './mixxx-test') - env.Alias('test', run_test) - - if default: - Default(copy_test_bin) - else: - env.Alias('mixxx-test', test_bin) - if default: - Default(test_bin) - - -# If the 'test' flag is 1, then build the mixxx-test target by default. If -# 'test' is in the target list then run mixxx-test. -build_tests_by_default = int(build.flags['test']) != 0 -build_tests = 'mixxx-test' in COMMAND_LINE_TARGETS -run_tests = 'test' in COMMAND_LINE_TARGETS -if build_tests or run_tests or build_tests_by_default: - define_test_targets(default=build_tests_by_default) - -def construct_version(build, mixxx_version, branch_name, vcs_revision): - if branch_name.startswith('release-'): - branch_name = branch_name.replace('release-', '') - - # Include build type in the filename. - build_type = 'release' if build.build_is_release else 'debug' - - # New, simpler logic: mixxx version, branch name, git revision, - # release/build. Example: mixxx-1.12.0-master-gitXXXX-release - return "%s-%s-%s%s-%s" % (mixxx_version, branch_name, vcs_name, - vcs_revision, build_type) - -def ubuntu_construct_version(build, mixxx_version, branch_name, vcs_revision, - ubuntu_version, distro_version): - # The format of a Debian/Ubuntu version is: - # - # [epoch:]upstream_version[-debian_revision] - # - # A detailed description of the valid characters and sorting order of - # versions can be found here: - # https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version - # - # For package upgrades to work correctly, we want the following - # orderings on package versions: - # - # nightly build < pre-alpha < alpha < beta < rc1 < rc2 < final release - # - # The sorting rules are complicated but the key detail is: "The lexical - # comparison is a comparison of ASCII values modified so that all the - # letters sort earlier than all the non-letters and so that a tilde - # sorts before anything, even the end of a part." - # - # The Mixxx version stored in src/defs_version.h (the "mixxx_version" - # parameter to this function) is formatted like: - # - # Pre Alpha: 2.0.0-alpha-pre - # Alpha: 2.0.0-alpha - # Beta: 2.0.0-beta - # RC: 2.0.0-rc1 - # Final: 2.0.0 - # - # Since hyphens are a separator character between the upstream version - # and Debian version, we replace these with tildes. - # - # Other goals: - # - We would like to know the branch and commit of a package. - # - We would like the PPA to trump the official Debian package. - # - # The following versions are sorted from low to high order: - # 1.9.9 - # 2.0.0~alpha~pre - # 2.0.0~alpha - # 2.0.0~beta~pre - # 2.0.0~beta - # 2.0.0~dfsg4 <- official Debian package version - # 2.0.0~rc1 - # 2.0.0 - # 2.0.1~alpha~pre - # - # Our official Debian packages have a ~dfsg section, so in this case an - # rc1 package in our PPA would trump an official Debian package - # (probably not what we want but not too bad since we would probably - # publish a "2.0.0" final to our PPA before the official Debian package - # is even released. - # - # Note in the above sorted list that if the branch name were included - # after the mixxx_version, 2.0.0~master would sort earlier than - # 2.0.0~rc1~master! To prevent branch and revision tags from - # interfering with package ordering we include them in the - # debian_revision portion of the version. This ensures they are only - # used for sorting if the upstream version of two packages is identical. - upstream_version = mixxx_version.replace('-', '~') - assert '_' not in upstream_version - - # Strip underscores and dashes in the branch name. - branch_name = branch_name.strip('_-') - assert branch_name and branch_name != '(no branch)' - - return "%s-%s~%s~%s%s~%s" % (upstream_version, ubuntu_version, branch_name, - vcs_name, vcs_revision, distro_version) - -#Set up the install target -#========================= - -#Mixxx binary -binary_files = [mixxx_bin]; -if test_bin is not None: - binary_files.append(test_bin) - -if build.bundle_pdbs: - binary_files.append(env.SideEffect('mixxx.pdb', mixxx_bin)) - -#Skins -skin_files = Glob('#res/skins/*') - -#Controller mappings -controllermappings_files = Glob('#res/controllers/*') - -# Translation files -# QT 5 translations have been separated into several files, and most of the qt_xx.qm files contain just shortcuts to load the qtbase, qtmultimedia etc files. -translation_files = Glob('#res/translations/*.qm') + Glob(os.path.join(build.env['QTDIR'], 'translations/qt_*.qm')) + Glob(os.path.join(build.env['QTDIR'], 'translations/qtbase_*.qm')) + Glob(os.path.join(build.env['QTDIR'], 'translations/qtmultimedia_*.qm')) + Glob(os.path.join(build.env['QTDIR'], 'translations/qtscript_*.qm')) + Glob(os.path.join(build.env['QTDIR'], 'translations/qtxmlpatterns_*.qm')) - - -# Font files -font_files = Glob('#res/fonts/*') - -#Keyboard mapping(s) -keyboardmappings_files = Glob('#res/keyboard/*') - -#Documentation -docs_files = Glob('#./LICENSE') -docs_files += Glob('#./README') -docs_files += Glob('#./Mixxx-Manual.pdf') - -#.desktop file for KDE/GNOME menu -dotdesktop_files = Glob('#res/linux/mixxx.desktop') - -#.appdata.xml file for KDE/GNOME AppStream iniative -dotappstream_files = Glob('#res/linux/mixxx.appdata.xml') - -#udev rule file for USB HID and Bulk controllers -hidudev_files = Glob('#res/linux/mixxx-usb-uaccess.rules') - -#Icon file for menu entry -icon_files = Glob('#res/images/mixxx_icon.svg') - -#Images for preferences dialog -image_files = Glob('#res/images/preferences/*') # These are compiled in to the "mixxx" binary through mixxx.qrc - -#Windows DLLs - -dll_files = [] -if build.toolchain_is_msvs and not build.static_dependencies: - # skip the MSVC DLLs in case they're in there too - dll_files.extend(Glob('%s/*.dll' % build.winlib_path)) - dll_files.extend(Glob('%s/lib/*.dll' % build.winlib_path)) - - if build.bundle_pdbs: - dll_files.extend(Glob('%s/*.pdb' % build.winlib_path)) - dll_files.extend(Glob('%s/lib/*.pdb' % build.winlib_path)) -elif build.crosscompile and build.platform_is_windows and build.toolchain_is_gnu and not build.static_dependencies: - # 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) - -qt_modules = depends.Qt.enabled_modules(build) - -if build.platform_is_windows: - suffix = 'd.dll' if build.build_is_debug else '.dll' - if not build.static_qt: - qt_modules = ['$QTDIR/lib/' + module.replace('Qt', 'Qt5') + suffix - for module in qt_modules] - dll_files.extend(qt_modules) - # https://doc.qt.io/qt-5/windows-deployment.html - # "If dynamic OpenGL is used, you additionally need to include the - # libraries required for ANGLE and software rendering. For ANGLE, both - # libEGL.dll and libGLESv2.dll from Qt's lib directory are required as - # well as the HLSL compiler from DirectX. The HLSL compiler library, - # d3dcompiler_XX.dll, where XX is the version number that ANGLE - # (libGLESv2) was linked against." - dll_files.extend(['$QTDIR/bin/libEGL' + suffix, - '$QTDIR/bin/libGLESv2' + suffix]) - d3dcompiler_path = util.find_d3dcompiler_dll(build.env) - if d3dcompiler_path: - dll_files.append(d3dcompiler_path) - -# Qt imageformats plugin -imgfmtdll_files = [] -qt_imagesformats = depends.Qt.enabled_imageformats(build) - -suffix = 'd.dll' if build.build_is_debug else '.dll' -if not build.static_qt: - imgfmtdll_files.extend(['$QTDIR/plugins/imageformats/' + module + suffix for module in qt_imagesformats]) -# We don't have Qt's dll pdb files in our release build environements, so only if build is debug -pdbSuffix = 'd.pdb' if (build.bundle_pdbs and build.build_is_debug) else '' -if pdbSuffix: - imgfmtdll_files.extend(['$QTDIR/plugins/imageformats/' + module + pdbSuffix for module in qt_imagesformats]) - -sqldll_files = [] -if int(flags.get('qt_sqlite_plugin', 0)): - # TODO(rryan): Add the SQLite DLL For Qt5. - pass - -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, - env.get('SHAREDIR', default='share')) - unix_bin_path = os.path.join(install_root, - env.get('BINDIR', default='bin')) - - binary = env.Install(unix_bin_path, binary_files) - skins = env.Install(os.path.join(unix_share_path, 'mixxx', 'skins'), skin_files) - fonts = env.Install(os.path.join(unix_share_path, 'mixxx', 'fonts'), font_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) - dotdesktop = env.Install(os.path.join(unix_share_path, 'applications'), dotdesktop_files) - dotappstream = env.Install(os.path.join(unix_share_path, 'appdata'), dotappstream_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) - - # NOTE(rryan): Hack to detect when we're Debian packaging. - building_debian_package = 'debian/tmp/usr' in install_root - udev_root = '/etc/udev/rules.d' - hidudev = env.Install(udev_root, hidudev_files) - - #Makes each of those Install builders get fired off when you run "scons install" :) - env.Alias('install', binary) - env.Alias('install', skins) - env.Alias('install', fonts) - env.Alias('install', controllermappings) - env.Alias('install', translations) - env.Alias('install', keyboardmappings) - env.Alias('install', docs) - env.Alias('install', dotdesktop) - env.Alias('install', dotappstream) - env.Alias('install', icon) - - if not building_debian_package and os.access(udev_root, os.W_OK): - env.Alias('install', hidudev) - - -#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" - - # In Qt 5, the SQLite driver was moved out of QtSql and into a plugin. - sql_dylibs = ["libqsqlite.dylib"] - - qt_plugins = ( - [("iconengines", e) for e in ["libqsvgicon.dylib"]] + - # Left out libqmng and libqtiff to save space. - [("imageformats", e) for e in - ["libqgif.dylib", "libqjpeg.dylib", "libqsvg.dylib"]] + - # Cocoa support moved to a plugin in Qt 5. - [("platforms", "libqcocoa.dylib")] + - [("sqldrivers", e) for e in sql_dylibs] + - [("styles", "libqmacstyle.dylib")] - ) - - resource_map = {} - for tfile in translation_files: - resource_map[str(tfile)] = 'translations' - - qtdir = build.env['QTDIR'] - qt_frameworks = depends.Qt.find_framework_libdir(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/'), - Dir('#res/controllers/'), - Dir('#res/fonts/'), - translation_files, - Dir('#res/keyboard/'), - Dir('#res/doc/'), - Dir(menu_nib), - File("#README"), - File("#LICENSE")] - bundle = env.App( - "Mixxx_bundle", - 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 :( - APP_RESOURCES_MAP=resource_map, - IDENTIFIER="org.mixxx.mixxx", - DISPLAY_NAME="Mixxx", - VERSION=mixxx_version, - SHORT_VERSION=mixxx_version, - COPYRIGHT="Copyright © 2001-%s Mixxx Development Team" % datetime.datetime.now().year, - MINIMUM_OSX_VERSION=util.get_osx_min_version(), - CATEGORY="public.app-category.music", - OTOOL_LOCAL_PATHS=otool_local_paths, - OTOOL_SYSTEM_PATHS=otool_system_paths, - FOR_APP_STORE=int(build.flags['macappstore']) > 0, - ) - 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_codesign', - 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.AlwaysBuild(codesign) - env.Alias('sign', codesign) - - package_name = 'mixxx' - package_version = 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) - controllermappings = env.Install(os.path.join(base_dist_dir, "controllers"), controllermappings_files) - fonts = env.Install(os.path.join(base_dist_dir, "fonts"), font_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) - docs = env.Install(os.path.join(base_dist_dir, "doc/"), docs_files) - #icon = env.Install(base_dist_dir+"", icon_files) - dlls = env.Install(base_dist_dir+"/", dll_files) - binary = env.Install(base_dist_dir+"/", binary_files) - - #Always trigger these install builders when compiling on Windows - env.Alias('mixxx', skins) - env.Alias('mixxx', controllermappings) - env.Alias('mixxx', fonts) - env.Alias('mixxx', translations) - env.Alias('mixxx', keyboardmappings) - env.Alias('mixxx', docs) - env.Alias('mixxx', dlls) - #env.Alias('mixxx', icon) - env.Alias('mixxx', binary) - - binaries_to_codesign = [binary, dlls] - - # imageformats DLL - if imgfmtdll_files: - imageformats_dll = env.Install(os.path.join(base_dist_dir, "imageformats"), imgfmtdll_files) - binaries_to_codesign.append(imageformats_dll) - env.Alias('mixxx', imageformats_dll) - - # QSQLite DLL - if sqldll_files: - sql_dlls = env.Install(os.path.join(base_dist_dir, "sqldrivers"), sqldll_files) - binaries_to_codesign.append(sql_dlls) - env.Alias('mixxx', sql_dlls) - - if 'sign' in COMMAND_LINE_TARGETS: - codesign_subject_name = SCons.ARGUMENTS.get('windows_codesign_subject_name', '') - if not codesign_subject_name: - raise Exception('Code-signing was requested but windows_codesign_subject_name was not provided.') - codesign = env.SignTool( - 'Mixxx_signtool', - binaries_to_codesign, - SUBJECT_NAME=codesign_subject_name) - env.Alias('sign', codesign) - -def BuildRelease(target, source, env): - print("==== Mixxx Post-Build Checks ====") - print("You have built version %s" % mixxx_version) - if build.build_is_debug: - print("YOU ARE ABOUT TO PACKAGE A DEBUG BUILD!!") - print("Binary has size ", end='') - 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("Installer file ", end='') - package_name = 'mixxx' - - package_version = construct_version(build, mixxx_version, branch_name, - vcs_revision) - arch = "x64" if build.machine_is_64bit else "x86" - msi_name = '%s-%s-%s.msi' % (package_name, package_version, arch) - print(msi_name) - 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("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') - - #if (raw_input("Go ahead and build installer (yes/[no])? ") == "yes"): - if True: - # TODO(XXX): Installing a runtime isn't specific to MSVS? - if build.toolchain_is_msvs: - redist_file = 'vc_redist.%s.exe' % arch - print("Searching for the Visual C++ DLL installer package" + redist_file) - # Check for the runtime installer in the winlib root. - redist_path = '%s' % os.path.join(build.winlib_path, redist_file) - print(" ", redist_path,) - if not os.path.isfile(redist_path): - raise Exception('Could not find the MSVC++ runtime installer.') - - print("Now building installation package...") - - print("Looking for WIX Toolset...") - wix_path = None - if not build.crosscompile and build.platform_is_windows: - wix_directory = os.getenv('WIX') - wix_path = '%s' % os.path.join(wix_directory, "bin") - elif build.crosscompile and build.platform_is_windows: - # TODO(XXX) How to handle that ? what does this exactly means ? - raise NotImplementedError - - if not wix_directory: - raise Exception ('Cannot find WIX Toolkit. Do you have it installed?') - else: - print(" Found Wix Toolset in " + wix_path) - - WinSDK_path = 'build\\wix' - - if not os.path.isfile(os.path.join(WinSDK_path, 'wisubstg.vbs')): - raise Exception ('can not find ' + WinSDK_path + '\wisubstg.vbs') - - if not os.path.isfile(os.path.join(WinSDK_path, 'WiLangId.vbs')): - raise Exception ('can not find ' + WinSDK_path + '\WiLangId.vbs') - - # Generating random ProductID (should change on every run) - # and put it in mixxx.wxs using the template - ProductID = str(uuid.uuid1()).upper() - with open("build/wix/ProductID.wxi.in", "rt") as fin: - with open("build/wix/ProductID.wxi", "wt") as fout: - for line in fin: - fout.write(line.replace('@PRODUCT_ID@', ProductID)) - fin.close() - fout.close() - - # The default language - defaultLanguage="en-us" - # The langIds contained in the installer. starting with LangId of the default language - langIds="1033" - - winArch = "x64" if build.machine_is_64bit else "x86" - - # Auto-create wxs file for each subdir and compile them - print("*** Building intermediate files") - for subdir in next(os.walk(dist_dir))[1]: - print(" " + dist_dir + "\\" + subdir) - # Exclude doc and imageformats helper DLLs, they are bundled elsewhere - if subdir in ['doc', 'imageformats']: - continue - command = '"%(wix)s\\heat.exe" dir %(distdir)s\%(sub)s -nologo -sfrag -suid -ag -srd -cg %(sub)sComp -dr %(sub)sDir -out build\wix\subdirs\%(sub)s.wxs -sw5150 -var var.%(sub)sVar' % \ - {'wix': wix_path, - 'distdir': dist_dir, - 'sub': subdir} - print("Using Command: " + command) - subprocess.check_call(command) - command = '"%(wix)s\\candle.exe" -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -d%(sub)sVar=%(distdir)s\%(sub)s -arch %(arch)s -out build\wix\subdirs\%(sub)s.wixobj build\wix\subdirs\%(sub)s.wxs' % \ - {'wix': wix_path, - 'winlibpath': build.winlib_path, - 'arch': winArch, - 'distdir': dist_dir, - 'sub': subdir} - print("Using Command: " + command) - subprocess.check_call(command) - - # Handle QT's imageformats helper DLLs if dynamic QT - imageformats = "no" - if os.path.exists(os.path.join(dist_dir,"imageformats")) and not build.static_qt: - imageformats = "yes" - command = '"%(wix)s\\heat.exe" dir %(distdir)s\%(sub)s -nologo -sfrag -suid -ag -srd -cg %(sub)sComp -dr %(sub)sDir -out build\wix\subdirs\%(sub)s.wxs -sw5150 -var var.%(sub)sVar' % \ - {'wix': wix_path, - 'distdir': dist_dir, - 'sub': "imageformats"} - print("Using Command: " + command) - subprocess.check_call(command) - - command = '"%(wix)s\\candle.exe" -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -d%(sub)sVar=%(distdir)s\%(sub)s -arch %(arch)s -out build\wix\subdirs\%(sub)s.wixobj build\wix\subdirs\%(sub)s.wxs' % \ - {'wix': wix_path, - 'winlibpath': build.winlib_path, - 'arch': winArch, - 'distdir': dist_dir, - 'sub': "imageformats"} - print("Using Command: " + command) - subprocess.check_call(command) - - # Harvest main DLL from install dir - command = '"%(wix)s\\heat.exe" dir %(distdir)s -nologo -sfrag -suid -ag -srd -cg mainDLLCompGroup -dr INSTALLDIR -out build\wix\subdirs\mainDLL.wxs -sw5150 -var var.SourceDir -t build\wix\only-dll.xslt' % \ - {'wix': wix_path, - 'distdir': dist_dir} - print("Using Command: " + command) - subprocess.check_call(command) - - command = '"%(wix)s\\candle.exe" -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -dSourceDir=%(distdir)s -arch %(arch)s -out build\wix\subdirs\mainDLL.wixobj build\wix\subdirs\mainDLL.wxs' % \ - {'wix': wix_path, - 'winlibpath': build.winlib_path, - 'arch': winArch, - 'distdir': dist_dir} - print("Using Command: " + command) - subprocess.check_call(command) - - # Harvest main PDB from install dir if they exist - isPdb = "no" - if build.bundle_pdbs and glob.glob(os.path.join(dist_dir, "*.pdb")): - isPdb = "yes" - command = '"%(wix)s\\heat.exe" dir %(distdir)s -nologo -sfrag -suid -ag -srd -cg mainPDBCompGroup -dr INSTALLDIR -out build\wix\subdirs\mainPDB.wxs -sw5150 -var var.SourceDir -t build\wix\only-pdb.xslt' % \ - {'wix': wix_path, - 'distdir': dist_dir} - print("Using Command: " + command) - subprocess.check_call(command) - - command = '"%(wix)s\\candle.exe" -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -dSourceDir=%(distdir)s -arch %(arch)s -out build\wix\subdirs\mainPDB.wixobj build\wix\subdirs\mainPDB.wxs' % \ - {'wix': wix_path, - 'winlibpath': build.winlib_path, - 'arch': winArch, - 'distdir': dist_dir} - print("Using Command: " + command) - subprocess.check_call(command) - - # Compile main wix files - command = '"%(wix)s\\candle.exe" -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -dImageformats=%(isimageformats)s -dPDB=%(isPDB)s -arch %(arch)s -out build\wix\mixxx.wixobj build\wix\mixxx.wxs' % \ - {'wix': wix_path, - 'winlibpath': build.winlib_path, - 'isimageformats': imageformats, - 'isPDB': isPdb, - 'arch': winArch} - print("Using Command: " + command) - subprocess.check_call(command) - - # Build package for default language - print("*** Building package for default language " + defaultLanguage) - command = '"%(wix)s\\light.exe" -cc .\ -nologo -sw1076 -spdb -ext WixUIExtension -cultures:%(deflang)s -loc build\wix\Localization\mixxx_%(deflang)s.wxl -out %(package_name)s build\wix\*.wixobj build\wix\subdirs\*.wixobj' % \ - {'wix': wix_path, - 'deflang': defaultLanguage, - 'package_name': 'part.' + msi_name} - print("Using Command: " + command) - subprocess.check_call(command) - - bundlelocfile = open("build/wix/bundle/bundleloc.wxs", "w") - bundlelocfile.write("<?xml version='1.0' encoding='windows-1252'?>\n") - bundlelocfile.write("<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>\n") - bundlelocfile.write(" <Fragment Id='FragmentBundleLoc'>\n") - bundlelocfile.write(" <PayloadGroup Id='BundleLoc'>\n") - - for file in glob.glob('build\wix\Localization\mixxx_*.wxl'): - doc = minidom.parse(file) - wixloc = doc.getElementsByTagName("WixLocalization")[0] - culture = wixloc.getAttribute("Culture") - strings = doc.getElementsByTagName("String") - LCID = None - for string in strings: - if string.getAttribute('Id') == "Language": - LCID = string.firstChild.data - break - - if not LCID: - print("LCID not found, skipping file " + file) - continue - - bundlelocfile.write(" <Payload Id=\"thm-%(culture)s\" Compressed=\"yes\" Name=\"%(LCID)s\\thm.wxl\" SourceFile=\"..\\Localization\\mixxx_%(culture)s.wxl\" />\n" %\ - {'culture': culture, - 'LCID': LCID} - ) - - # Do not build localized MSI if it's default language - if culture == defaultLanguage: - continue - - print("*** Building package transform for locale %(culture)s LangID %(LCID)s" % \ - {'culture': culture, - 'LCID': LCID}) - - command = '"%(wix)s\\light.exe" -cc .\ -reusecab -nologo -sw1076 -spdb -ext WixUIExtension -cultures:%(lang)s,%(deflang)s -loc %(wxl_file)s -out %(lang)s.msi build\wix\*.wixobj build\wix\subdirs\*.wixobj' % \ - {'wix': wix_path, - 'lang': culture, - 'deflang': defaultLanguage, - 'wxl_file': file} - print("Using Command: " + command) - subprocess.check_call(command) - - command = '"%(wix)s\\torch.exe" -nologo -p -t language %(package_name)s %(lang)s.msi -o %(lang)s.mst' % \ - {'wix': wix_path, - 'lang': culture, - 'package_name': 'part.' + msi_name} - print("Using Command: " + command) - subprocess.check_call(command) - - command = 'cscript "%(winsdk)s\wisubstg.vbs" %(package_name)s %(lang)s.mst %(langid)s' % \ - {'winsdk': WinSDK_path, - 'lang': culture, - 'package_name': 'part.' + msi_name, - 'langid': LCID} - print("Using Command: " + command) - subprocess.check_call(command) - - langIds = langIds + "," + LCID - os.remove(culture + ".msi") - os.remove(culture + ".mst") - - print("*** Add all supported languages to MSI Package attribute") - command = 'cscript "%(winsdk)s\WiLangId.vbs" %(package_name)s Package %(langid)s' % \ - {'winsdk': WinSDK_path, - 'package_name': 'part.' + msi_name, - 'langid': langIds} - print("Using Command: " + command) - subprocess.check_call(command) - - bundlelocfile.write(" </PayloadGroup>\n") - bundlelocfile.write(" </Fragment>\n") - bundlelocfile.write("</Wix>\n") - bundlelocfile.close() - - # Everything is OK, now rename the msi to final name - if os.path.isfile(msi_name): - os.remove(msi_name) - os.rename('part.' + msi_name, msi_name) - - print("*** Compiling Bundle") - # Compile bundle wix file - command = '"%(wix)s\\candle.exe" -ext WixUtilExtension -ext WixBalExtension -nologo -dWINLIBPATH=%(winlibpath)s -dPlatform=%(arch)s -dMSIPackage=%(package_name)s -arch %(arch)s -out build\\wix\\bundle\\bundle.wixobj build\\wix\\ |