Skip to content

Commit

Permalink
Build library objects in the SConscript variant_dir.
Browse files Browse the repository at this point in the history
SCons has a feature that lets you declare a repository-root absolute
path to a file (e.g. "#lib/soundtouch/..."). Using this feature
prevents SCons from automatically re-directing built artifacts to a
variant_dir. To work around this, this commit moves src/SConscript and
src/SConscript.env to the root, and changes all paths in SConscripts
to use SConscript-relative paths.

This commit also switches to building an explicit static library for
vamp-hostdk, vamp-sdk, and soundtouch when internal linking is enabled
and the VAMP plugin now uses the system soundtouch if it is present.

Fixes Bug #1191327 and Bug #1617802.
  • Loading branch information
rryan committed Oct 14, 2018
1 parent f2225f4 commit 73f8c85
Show file tree
Hide file tree
Showing 11 changed files with 790 additions and 814 deletions.
84 changes: 42 additions & 42 deletions src/SConscript → SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ flags = build.flags
# both mixxx and mixxx-test.
mixxx_lib = env.StaticLibrary('libmixxx',
[source for source in sources
if str(source) != 'main.cpp'])
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('qrc_mixxx', '#res/mixxx.qrc'))
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('main.cpp')
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")
fo = open(File('src/mixxx.rc.include').abspath, "w")

str_list = []
str_list.append('#define VER_FILEVERSION ')
Expand Down Expand Up @@ -80,7 +80,7 @@ if build.platform_is_windows:
fo.write(''.join(str_list))
fo.close()

mixxx_rc = env.RES('#src/mixxx.rc')
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'])
Expand Down Expand Up @@ -110,25 +110,25 @@ else:
test_bin = None
def define_test_targets(default=False):
global test_bin
test_files = Glob('test/*.cpp', strings=True)
test_files = Glob('src/test/*.cpp', strings=True)
test_env = env.Clone()
test_env.Append(CPPPATH="#lib/gtest-1.7.0/include")
test_env.Append(CPPPATH="#lib/gmock-1.7.0/include")
test_env.Append(CPPPATH="#lib/benchmark/include")
test_files = [test_env.StaticObject(filename)
if filename !='main.cpp' else filename
for filename in test_files]
test_sources = test_files

test_env.Append(LIBPATH="#lib/gtest-1.7.0/lib")
test_env.Append(CPPPATH="lib/gtest-1.7.0/include")
test_env.Append(LIBPATH="lib/gtest-1.7.0")
test_env.Append(LIBS=['gtest'])

test_env.Append(LIBPATH="#lib/gmock-1.7.0/lib")
test_env.Append(CPPPATH="lib/gmock-1.7.0/include")
test_env.Append(LIBPATH="lib/gmock-1.7.0")
test_env.Append(LIBS=['gmock'])

test_env.Append(LIBPATH="#lib/benchmark/lib")
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'])
Expand All @@ -144,10 +144,10 @@ def define_test_targets(default=False):
# Currently both executables are built with /subsystem:windows
# and the console is attached manually
test_bin = test_env.Program(
'mixxx-test', [test_sources, mixxx_qrc, mixxx_rc],
'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_sources, mixxx_qrc])
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"))
Expand Down Expand Up @@ -270,39 +270,39 @@ if build.bundle_pdbs:
libmixxxminimal_vamp_plugin = mixxxminimal_plugins

#Skins
skin_files = Glob('#res/skins/*')
skin_files = Glob('res/skins/*')

#Controller mappings
controllermappings_files = Glob('#res/controllers/*')
controllermappings_files = Glob('res/controllers/*')

# Translation files
translation_files = Glob('#res/translations/*.qm') + Glob(os.path.join(build.env['QTDIR'], 'translations/qt_*.qm'))
translation_files = Glob('res/translations/*.qm') + Glob(os.path.join(build.env['QTDIR'], 'translations/qt_*.qm'))

# Font files
font_files = Glob('#res/fonts/*')
font_files = Glob('res/fonts/*')

#Keyboard mapping(s)
keyboardmappings_files = Glob('#res/keyboard/*')
keyboardmappings_files = Glob('res/keyboard/*')

#Documentation
docs_files = Glob('#./LICENSE')
docs_files += Glob('#./README')
docs_files += Glob('#./Mixxx-Manual.pdf')
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')
dotdesktop_files = Glob('res/linux/mixxx.desktop')

#.appdata.xml file for KDE/GNOME AppStream iniative
dotappstream_files = Glob('#res/linux/mixxx.appdata.xml')
dotappstream_files = Glob('res/linux/mixxx.appdata.xml')

#udev rule file for USB HID and Bulk controllers
hidudev_files = Glob('#res/linux/mixxx.usb.rules')
hidudev_files = Glob('res/linux/mixxx.usb.rules')

#Icon file for menu entry
icon_files = Glob('#res/images/mixxx_icon.svg')
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
image_files = Glob('res/images/preferences/*') # These are compiled in to the "mixxx" binary through mixxx.qrc

#Windows DLLs

Expand Down Expand Up @@ -421,7 +421,7 @@ if build.platform_is_osx and 'bundle' in COMMAND_LINE_TARGETS:
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"
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"]
Expand Down Expand Up @@ -470,16 +470,16 @@ if build.platform_is_osx and 'bundle' in COMMAND_LINE_TARGETS:
#qtplugindir = '/Developer/Applications/Qt/'
qtplugindir = qtdir
sources = [mixxx_bin,
'#res/osx/application.icns',
Dir('#res/skins/'),
Dir('#res/controllers/'),
Dir('#res/fonts/'),
'res/osx/application.icns',
Dir('res/skins/'),
Dir('res/controllers/'),
Dir('res/fonts/'),
translation_files,
Dir('#res/keyboard/'),
Dir('#res/doc/'),
Dir('res/keyboard/'),
Dir('res/doc/'),
Dir(menu_nib),
File("#README"),
File("#LICENSE")]
File("README"),
File("LICENSE")]
bundle = env.App(
"Mixxx_bundle",
sources,
Expand Down Expand Up @@ -527,7 +527,7 @@ if build.platform_is_osx and 'bundle' in COMMAND_LINE_TARGETS:
env.Alias('package', dmg)

if build.platform_is_windows:
base_dist_dir = '#' + dist_dir
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)
Expand Down Expand Up @@ -1128,5 +1128,5 @@ versiondebbld = Builder(action = BuildUbuntuPackage) #, suffix = '.foo', src_suf
env.Append(BUILDERS = {'BuildUbuntuPackage' : versiondebbld})

if 'makeubuntu' in COMMAND_LINE_TARGETS:
makeubuntu = env.BuildUbuntuPackage("blah", "defs_version.h" ) #(binary_files)
makeubuntu = env.BuildUbuntuPackage("blah", "src/defs_version.h" ) #(binary_files)
env.Alias('makeubuntu', makeubuntu)
25 changes: 14 additions & 11 deletions src/SConscript.env → SConscript.env
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,29 @@ import shutil

from build import util, mixxx, depends

print('SConscript.env cwd: ' + os.getcwd())
Import('build')

# Grab the created environment from the MixxxBuild
env = build.env

# Check for old build.h file and delete it if it exists
defs = str(SCons.Script.File('#src/build.h'))
if os.path.exists(defs):
print("Deleting deprecated build file: %s" % defs)
os.remove(defs)
# We are in the variant_dir (win|mac|lin)XX_build, and the 'src' subdirectory
# may not exist yet.
try:
os.mkdir('src')
except:
pass

if os.path.exists(os.path.join('..', 'build.h')):
# TODO(rryan): This logic should be written in a more SCons-friendly way, since
# it depends on the cwd being the variant_dir to work properly.
if os.path.exists('../build.h'):
# If a build.h exists in the project root mixxx/ directory then use that
# instead of writing our own. This is mostly since when we build Debian
# packages we don't have any of the Bazaar metadata so we can't write one
# packages we don't have any of the Git metadata so we can't write one
# ourselves.
shutil.copy(os.path.join('..', 'build.h'), 'build.h')
shutil.copy('../build.h', 'src/build.h')
else:
util.write_build_header('build.h')

util.write_build_header('src/build.h')

conf = Configure(env, custom_tests = { 'CheckForPKGConfig' : util.CheckForPKGConfig,
'CheckForPKG' : util.CheckForPKG })
Expand Down Expand Up @@ -128,7 +131,7 @@ build_flags = ' '.join(sorted(
[('%s=%s' % (k,v) if v is not None else k) for k,v in build.flags.items() if v is not None]))

### Put flags info into a file
with open("build.h","a") as f:
with open("src/build.h", "a") as f:
f.write('#define BUILD_FLAGS "' + build_flags + '"\n')

# Print the build flags. This is useful if the flags have been cached,
Expand Down
24 changes: 15 additions & 9 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ available_features = [features.Mad,
# "Features" of dubious quality
features.PerfTools,
features.AsmLib,
features.IPod,
features.FFMPEG,

# Experimental features
Expand All @@ -75,22 +74,29 @@ Export('build')

# Run our configuration stuff to setup our build environment (detect
# platform/arch, find libraries, etc)
SConscript(File('src/SConscript.env'), variant_dir=Dir(build.build_dir), duplicate=0)

# If the variant_dir does not exist then we will not chdir into it when calling
# SConscript.env, making the imperative logic (e.g. writing build.h) in
# SConscript.env behave differently on the first invocation vs. subsequent
# invocations.
try:
os.mkdir(build.build_dir)
except:
pass
SConscript('SConscript.env', variant_dir=build.build_dir, duplicate=0)

# Grab the list of sources generated by SConscript.env
Import('sources')

#Build Vamp minimal plugins
#VariantDir("vamp-plugins", "src", duplicate=0)
mixxxminimal_depends = [ depends.SoundTouch ]
# Build VAMP plugins.
mixxxminimal_plugins = SConscript(
File('vamp-plugins/SConscript'),
variant_dir=Dir(build.build_dir + "/vamp-plugins"),
duplicate=0, exports=['build', 'mixxxminimal_depends'])
'vamp-plugins/SConscript',
variant_dir=build.build_dir + "/vamp-plugins",
duplicate=0, exports=['build'])

# Setup and build the "mixxx" executable target. Also sets up our install
# targets for each platform.
SConscript(File('src/SConscript'), variant_dir=Dir(build.build_dir), duplicate=0,
SConscript('SConscript', variant_dir=build.build_dir, duplicate=0,
exports=['build', 'sources', 'mixxxminimal_plugins'])

#On OS X, if the bundle has been built, copy it up:
Expand Down
Loading

0 comments on commit 73f8c85

Please sign in to comment.