Line 0
Link Here
|
|
|
1 |
import os |
2 |
import sys |
3 |
import glob |
4 |
import SCons |
5 |
import shutil |
6 |
|
7 |
# BIG FAT WARNING: |
8 |
# Make sure you use TABS for indentation, NOT spaces! (Python doesn't like spaces, be forewarned!) |
9 |
# |
10 |
# #### #### ########## ##### ##### ##### ##### ##### ##### |
11 |
# ###### ###### #### ##### ##### ##### ##### ##### ##### |
12 |
# #### ## ## #### #### ######## ######## ######## |
13 |
# #### # #### #### ##### ##### ##### ##### ##### ##### |
14 |
# #### #### ########## ##### ##### ##### ##### ##### ##### |
15 |
# |
16 |
# ############################################################################# |
17 |
# ######################################################################### |
18 |
# |
19 |
|
20 |
# |
21 |
#Useful functions |
22 |
# |
23 |
|
24 |
def getSVNRevision(): # GPL code taken from http://trac.zeitherrschaft.org/zzub/browser/trunk/SConstruct |
25 |
# if this is a repository, take the string from svnversion |
26 |
svnversionpath = env.WhereIs('svnversion', os.environ['PATH']) |
27 |
if os.path.isdir('../.svn') and (svnversionpath != None): # we always start in .obj for some reason, so we must use ../.svn |
28 |
rev = os.popen('svnversion ..').readline().strip() |
29 |
if rev != "" and rev != "exported": |
30 |
return rev |
31 |
return "" |
32 |
|
33 |
#Checks for OpenGL on all three platforms |
34 |
def CheckOpenGL(): |
35 |
if not conf.CheckLib('GL') and not conf.CheckLib('opengl32') and not conf.CheckCHeader('/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/gl.h'): |
36 |
print 'Did not find OpenGL development files, exiting!' |
37 |
Exit(1) |
38 |
|
39 |
if not conf.CheckLib('GLU') and not conf.CheckLib('glu32') and not conf.CheckCHeader('/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/glu.h'): |
40 |
print 'Did not find GLU development files, exiting!' |
41 |
Exit(1) |
42 |
#Workaround for SCONS not detecting frameworks on OS X |
43 |
if platform == 'osx': |
44 |
env.Append(LINKFLAGS = '-framework OpenGL') |
45 |
|
46 |
return |
47 |
|
48 |
#Checks for OGG/Vorbis on all three platforms |
49 |
def CheckOggVorbis(): |
50 |
#Check for Ogg and Vorbis on Linux, OS X, and Win32 |
51 |
if not conf.CheckLib('vorbisfile'): |
52 |
print 'Did not find libvorbisfile.a, libvorbisfile.lib, or the libvorbisfile development headers, exiting!' |
53 |
Exit(1) |
54 |
|
55 |
if not conf.CheckLib('vorbis'): |
56 |
print 'Did not find libvorbis.a, libvorbis.lib, or the libvorbisfile development headers, exiting!' |
57 |
Exit(1) |
58 |
|
59 |
if not conf.CheckLib('ogg'): |
60 |
print 'Did not find libogg.a, libogg.lib, or the libogg development headers, exiting!' |
61 |
Exit(1) |
62 |
|
63 |
# This function is here for historical reasons. It used to be easiest to build |
64 |
# Mixxx on OS X using the Vorbis and OGG "frameworks", and so this function |
65 |
# used to have some OS X-specific stuff in it. If you're building on OS X now |
66 |
# though, just install libvorbis and libogg from source. |
67 |
|
68 |
return |
69 |
|
70 |
#Check for FFMPEG support |
71 |
def CheckFFMPEG(conf, sources): |
72 |
flags_ffmpeg = ARGUMENTS.get('ffmpeg', 0) |
73 |
if int(flags_ffmpeg): |
74 |
if platform == 'linux': |
75 |
#Check for libavcodec, libavformat |
76 |
#I just randomly picked version numbers lower than mine for this - Albert |
77 |
if not conf.CheckForPKG('libavcodec', '51.20.0'): |
78 |
print 'libavcodec not found.' |
79 |
Exit(1) |
80 |
if not conf.CheckForPKG('libavformat', '51.1.0'): |
81 |
print 'libavcodec not found.' |
82 |
Exit(1) |
83 |
else: |
84 |
#Grabs the libs and cflags for ffmpeg |
85 |
env.ParseConfig('pkg-config libavcodec --silence-errors --cflags --libs') |
86 |
env.ParseConfig('pkg-config libavformat --silence-errors --cflags --libs') |
87 |
env.Append(CXXFLAGS = '-D__FFMPEGFILE__') |
88 |
else: |
89 |
# aptitude install libavcodec-dev libavformat-dev liba52-0.7.4-dev libdts-dev |
90 |
env.Append(LIBS = 'avcodec') |
91 |
env.Append(LIBS = 'avformat') |
92 |
env.Append(LIBS = 'z') |
93 |
env.Append(LIBS = 'a52') |
94 |
env.Append(LIBS = 'dts') |
95 |
env.Append(LIBS = 'gsm') |
96 |
env.Append(LIBS = 'dc1394_control') |
97 |
env.Append(LIBS = 'dl') |
98 |
env.Append(LIBS = 'vorbisenc') |
99 |
env.Append(LIBS = 'raw1394') |
100 |
env.Append(LIBS = 'avutil') |
101 |
env.Append(LIBS = 'vorbis') |
102 |
env.Append(LIBS = 'm') |
103 |
env.Append(LIBS = 'ogg') |
104 |
env.Append(CXXFLAGS = '-D__FFMPEGFILE__') |
105 |
sources += Split("""soundsourceffmpeg.cpp """) |
106 |
print "Not working FFMPEG support... enabled" |
107 |
else: |
108 |
print "Not working FFMPEG support... disabled" |
109 |
return |
110 |
|
111 |
|
112 |
# Checks for pkg-config on Linux |
113 |
def CheckForPKGConfig( context, version='0.0.0' ): |
114 |
context.Message( "Checking for pkg-config (at least version %s)... " % version ) |
115 |
ret = context.TryAction( "pkg-config --atleast-pkgconfig-version=%s" %version )[0] |
116 |
context.Result( ret ) |
117 |
return ret |
118 |
|
119 |
# Uses pkg-config to check for a minimum version |
120 |
def CheckForPKG( context, name, version="" ): |
121 |
if version == "": |
122 |
context.Message( "Checking for %s... \t" % name ) |
123 |
ret = context.TryAction( "pkg-config --exists '%s'" % name )[0] |
124 |
else: |
125 |
context.Message( "Checking for %s (%s or higher)... \t" % (name,version) ) |
126 |
ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0] |
127 |
context.Result( ret ) |
128 |
return ret |
129 |
|
130 |
|
131 |
def flatten(x): |
132 |
"""flatten(sequence) -> list |
133 |
|
134 |
Returns a single, flat list which contains all elements retrieved |
135 |
from the sequence and all recursively contained sub-sequences |
136 |
(iterables). |
137 |
|
138 |
Examples: |
139 |
>>> [1, 2, [3,4], (5,6)] |
140 |
[1, 2, [3, 4], (5, 6)] |
141 |
>>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)]) |
142 |
[1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]""" |
143 |
|
144 |
result = [] |
145 |
for el in x: |
146 |
#if isinstance(el, (list, tuple)): |
147 |
if hasattr(el, "__iter__"): |
148 |
result.extend(flatten(el)) |
149 |
else: |
150 |
result.append(el) |
151 |
return result |
152 |
|
153 |
def getFlags(env, argflag, default=0): |
154 |
""" |
155 |
* get value passed as an argument to scons as argflag=value |
156 |
* if no value is passed to scons use stored value |
157 |
* if no value is stored, use default |
158 |
Returns the value and stores it in env[argflag] |
159 |
""" |
160 |
flags = ARGUMENTS.get(argflag, -1) |
161 |
if int(flags) < 0: |
162 |
if env.has_key(argflag): |
163 |
flags = env[argflag] |
164 |
else: #default value |
165 |
flags = default |
166 |
env[argflag] = flags |
167 |
return flags |
168 |
1 |
169 |
###### MAIN LINE ###### |
170 |
####################### |
171 |
#Get the platform/OS that we're building on: |
172 |
if os.name == 'nt': |
173 |
print 'Platform: Windows' |
174 |
platform = 'win32' |
175 |
elif sys.platform == 'linux2': |
176 |
print 'Platform: Linux' |
177 |
platform = 'linux' |
178 |
elif sys.platform == 'darwin': |
179 |
print 'Platform: OS X' |
180 |
platform = 'osx' |
181 |
else: |
182 |
print 'Platform: Unknown (assuming Linux-like)' |
183 |
platform = 'linux' |
184 |
|
185 |
#Figure out what the QT path is |
186 |
if platform == 'linux': |
187 |
default_qtdir = '/usr/share/qt4' |
188 |
elif platform == 'osx': |
189 |
default_qtdir = '/usr/local/Trolltech/Qt-4.3.2/' |
190 |
elif platform == 'win32': |
191 |
default_qtdir = 'C:\\qt\\4.3.0' |
192 |
|
193 |
#Read the qtdir flag, if it was set explicitly |
194 |
flags_qtdir = ARGUMENTS.get('qtdir', default_qtdir) |
195 |
if not os.path.exists(flags_qtdir) and platform != 'osx': #OS X doesn't have a qt path. |
196 |
print "Error: QT path does not exist or QT4 is not installed." |
197 |
print "Please specify your QT path by running 'scons qtdir=[path]'" |
198 |
Exit(1) |
199 |
elif flags_qtdir.find("qt3") != -1 or flags_qtdir.find("qt/3") != -1: |
200 |
print "Error: Mixxx now requires QT4 instead of QT3 - please use your QT4 path with the qtdir build flag." |
201 |
Exit(1) |
202 |
else: |
203 |
print "QT path: " + flags_qtdir |
204 |
|
205 |
#Set up our environment, tell SCONS to use it's QT tools, and set some enviroment variables for it. |
206 |
#The ENV = os.environ part pulls in your existing environment variables. This is useful for awkward Linux setups |
207 |
#and on Windows where all the paths are set in the shell. |
208 |
if platform == 'linux' or platform == 'osx': |
209 |
env = Environment(tools=['default','qt4', 'msvs'], toolpath=['../', './'], QTDIR=flags_qtdir, QT_LIB='', ENV = os.environ) |
210 |
elif platform == 'win32': |
211 |
#Pull in the environment's variables for win32... |
212 |
env = Environment(tools=['default','qt4', 'msvs'], toolpath=['../', './'], QTDIR=flags_qtdir, QT_LIB='', VCINSTALLDIR = os.getenv('VCInstallDir'), ENV = os.environ) |
213 |
# env.Append(LIBPATH = (flags_qtdir + "/plugins/iconengines")) |
214 |
|
215 |
## Global cache directory |
216 |
## Put all project files in it so a rm -rf cache will clean up the config |
217 |
if not env.has_key('CACHEDIR'): |
218 |
env['CACHEDIR'] =os.getcwd()+ '/../../cache/' |
219 |
if not os.path.isdir(env['CACHEDIR']): |
220 |
os.mkdir(env['CACHEDIR']) |
221 |
|
222 |
## Avoid spreading .sconsign files everywhere - keep this line |
223 |
env.SConsignFile(env['CACHEDIR']+'/scons_signatures') |
224 |
|
225 |
#Hijack scons -h and --help |
226 |
cachefile = env['CACHEDIR'] + 'custom.py' |
227 |
opts = Options(cachefile) |
228 |
opts.Add('prefix', 'Set to your install prefix', '/usr/local') |
229 |
opts.Add('qtdir', 'Set to your QT4 directory', '/usr/share/qt4') |
230 |
opts.Add('djconsole', 'Set to 1 to enable Hercules support through libdjconsole', 0) |
231 |
opts.Add('djconsole_legacy', 'Set to 1 to enable legacy Hercules support (for Hercules MP3 Control only, not MK2', 0) |
232 |
opts.Add('hifieq', 'Set to 1 to enable high quality EQs', 1) |
233 |
opts.Add('ladspa', '(EXPERIMENTAL) Set to 1 to enable LADSPA plugin support', 0) |
234 |
opts.Add('ffmpeg', '(EXPERIMENTAL) Set to 1 to enable FFMPEG support', 0) |
235 |
opts.Add('vinylcontrol', 'Set to 1 to enable vinyl control support', 1) |
236 |
opts.Add('shoutcast', 'Set to 1 to enable shoutcast support', 0) |
237 |
opts.Add('msvshacks', 'Set to 1 to build properly with MS Visual Studio 2005 (Express users should leave this off)', 0) |
238 |
opts.Add('cmetrics', 'Set to 1 to enable crash reporting/usage statistics via Case Metrics (This should be disabled on development builds)', 0) |
239 |
opts.Add('optimize', 'Set to 1 to enable -O3 compiler optimizations. Set to 2 to enable Pentium 4 optimizations.', 1) |
240 |
if not platform == 'win32': |
241 |
opts.Add('gprof', '(DEVELOPER) Set to 1 to enable profiling using gprof', 0) |
242 |
opts.Add('tuned', '(EXPERIMENTAL) Set to 1 to optimise mixxx for this CPU', 0) |
243 |
#env = Environment(options = opts) |
244 |
opts.Update(env) |
245 |
Help(opts.GenerateHelpText(env)) |
246 |
|
247 |
# user-defined CXXFLAGS |
248 |
if os.environ.has_key('CXXFLAGS'): |
249 |
env.Append(CXXFLAGS = SCons.Util.CLVar( os.environ['CXXFLAGS'] )) |
250 |
|
251 |
### embed SVN version into build |
252 |
build_rev = getSVNRevision() |
253 |
### Old way - causes everything to be rebuilt each time the SVN ver moves. :( |
254 |
#if build_rev != '': |
255 |
# env.Append(CXXFLAGS = '-DBUILD_REV=\\"' + build_rev + '\\"') |
256 |
### Put version info into a file, so it doesn't force a rebuild of everything :) |
257 |
f = open("../.mixxx_version.svn","w") |
258 |
try: |
259 |
f.write('#define BUILD_REV "' + build_rev + '"\n') |
260 |
finally: |
261 |
f.close() |
262 |
|
263 |
#Mixxx sources to build |
264 |
sources = Split("""enginebuffercue.cpp input.cpp mixxxmenuplaylists.cpp trackplaylistlist.cpp mixxxkeyboard.cpp configobject.cpp controlobjectthread.cpp |
265 |
controlobjectthreadwidget.cpp controlobjectthreadmain.cpp controlevent.cpp controllogpotmeter.cpp controlobject.cpp controlnull.cpp controlpotmeter.cpp |
266 |
controlpushbutton.cpp controlttrotary.cpp controlbeat.cpp dlgpreferences.cpp dlgprefsound.cpp dlgprefmidi.cpp dlgprefplaylist.cpp dlgprefcontrols.cpp dlgbpmtap.cpp dlgprefbpm.cpp dlgbpmscheme.cpp dlgabout.cpp |
267 |
dlgprefeq.cpp dlgprefcrossfader.cpp enginebuffer.cpp enginebufferscale.cpp enginebufferscalelinear.cpp engineclipping.cpp enginefilterblock.cpp enginefilteriir.cpp enginefilter.cpp engineobject.cpp |
268 |
enginepregain.cpp enginevolume.cpp main.cpp midiobject.cpp midiobjectnull.cpp mixxx.cpp mixxxview.cpp |
269 |
soundsourcemp3.cpp soundsourceoggvorbis.cpp enginechannel.cpp enginemaster.cpp wwidget.cpp wpixmapstore.cpp wlabel.cpp wnumber.cpp wnumberpos.cpp wnumberrate.cpp wnumberbpm.cpp wknob.cpp wdisplay.cpp wvumeter.cpp wpushbutton.cpp wslidercomposed.cpp wslider.cpp wstatuslight.cpp enginedelay.cpp engineflanger.cpp enginespectralfwd.cpp mathstuff.cpp readerextract.cpp readerextractwave.cpp |
270 |
readerevent.cpp rtthread.cpp windowkaiser.cpp probabilityvector.cpp reader.cpp enginevumeter.cpp peaklist.cpp rotary.cpp log.cpp |
271 |
track.cpp trackcollection.cpp trackplaylist.cpp wtracktableview.cpp wtracktablemodel.cpp proxymodel.cpp xmlparse.cpp trackimporter.cpp parser.cpp parserpls.cpp parserm3u.cpp |
272 |
enginetemporal.cpp visual/visualbuffertemporal.cpp wavesummary.cpp bpmdetector.cpp bpmdetect.cpp bpmscheme.cpp peakfinder.cpp wavesegmentation.cpp soundsourceproxy.cpp woverview.cpp enginebeatseek.cpp |
273 |
enginebufferscalereal.cpp powermate.cpp hercules.cpp joystick.cpp mouse.cpp |
274 |
wvisualsimple.cpp wvisualwaveform.cpp visual/visualbackplane.cpp visual/texture.cpp visual/visualbox.cpp visual/visualbuffer.cpp visual/visualbuffersignal.cpp |
275 |
visual/visualbuffersignalhfc.cpp visual/visualbuffermarks.cpp visual/visualchannel.cpp visual/visualcontroller.cpp visual/visualdisplay.cpp visual/visualdisplaybuffer.cpp |
276 |
visual/light.cpp visual/material.cpp visual/picking.cpp visual/pickable.cpp visual/visualobject.cpp |
277 |
imginvert.cpp imgloader.cpp imgcolor.cpp wskincolor.cpp |
278 |
trackinfoobject.cpp soundsource.cpp |
279 |
midiledhandler.cpp |
280 |
sounddevice.cpp soundmanager.cpp sounddeviceportaudio.cpp |
281 |
enginevinylsoundemu.cpp enginesidechain.cpp wtracktablefilter.cpp |
282 |
wplaylistlistmodel.cpp libraryscanner.cpp libraryscannerdlg.cpp enginefilterbutterworth8.cpp enginexfader.cpp playerinfo.cpp wabstractcontrol.cpp""") |
283 |
|
284 |
#Crap we don't use anymore: |
285 |
#playerportaudio.cpp player.cpp playerproxy.cpp |
286 |
|
287 |
#Compile platform specific hardware support |
288 |
if platform == 'linux': |
289 |
sources += Split("""powermatelinux.cpp herculeslinux.cpp joysticklinux.cpp mouselinux.cpp """) |
290 |
#elif platform == 'win32': |
291 |
# sources += Split("""powermatewin.cpp mousewin.cpp """) |
292 |
|
293 |
#Compile platform specific MIDI support |
294 |
if platform == 'linux': |
295 |
sources += Split("""midiobjectalsaseq.cpp """) #ALSA Sequencer MIDI support for Linux |
296 |
env.Append(CXXFLAGS = '-D__ALSASEQMIDI__') |
297 |
elif platform == 'win32': |
298 |
sources += Split("""midiobjectwin.cpp """) #Windows MIDI support |
299 |
env.Append(CXXFLAGS = '-D__WINMIDI__') |
300 |
elif platform == 'osx': |
301 |
sources += Split("""midiobjectcoremidi.cpp """) #CoreMidi support for OS X |
302 |
env.Append(CXXFLAGS = '-D__COREMIDI__') |
303 |
|
304 |
|
305 |
#Set up the library path on Windows: |
306 |
if platform == 'win32': |
307 |
env.Append(CPPPATH='../../../mixxx-winlib') #If you add more directories, separate them with a semicolon (;) |
308 |
env.Append(LIBPATH='../../../mixxx-winlib') |
309 |
env.Append(LINKFLAGS = ['/nodefaultlib:libc.lib', '/nodefaultlib:libcd.lib', '/subsystem:windows', '/entry:mainCRTStartup']) |
310 |
|
311 |
#Check for dependencies if we're not doing a clean... |
312 |
|
313 |
if not env.GetOption('clean') and not SCons.Util.containsAny(os.sys.argv, ['-h', '--help']): |
314 |
conf = Configure(env, custom_tests = { 'CheckForPKGConfig' : CheckForPKGConfig, 'CheckForPKG' : CheckForPKG }) |
315 |
|
316 |
#TODO: Add all of the other configure checks as custom_tests properly. |
317 |
|
318 |
# On Posix default SCons.LIBPREFIX = 'lib', on Windows default SCons.LIBPREFIX = '' |
319 |
|
320 |
if not conf.CheckLibWithHeader('portaudio', 'portaudio.h', 'C'): |
321 |
print 'Did not find libportaudio.a, portaudio.lib, or the PortAudio-v19 development header files - exiting!' |
322 |
Exit(1) |
323 |
|
324 |
# if not conf.CheckLib(['$QTDIR/lib/qt-mt','$QTDIR/lib/qt-mt3']): |
325 |
# print 'Did not find libqt-mt.a or libqt-mt.lib, exiting!' |
326 |
# Exit(1) |
327 |
|
328 |
if not conf.CheckLib(['mad','libmad']): |
329 |
print 'Did not find libmad.a, libmad.lib, or the libmad development header files - exiting!' |
330 |
Exit(1) |
331 |
|
332 |
if not conf.CheckLib(['id3tag','libid3tag-release']): |
333 |
print 'Did not find libid3tag.a, libid3tag.lib, or the libid3tag development header files - exiting!' |
334 |
Exit(1) |
335 |
|
336 |
#Check for Ogg and Vorbis |
337 |
CheckOggVorbis() |
338 |
|
339 |
#Check for OpenGL (it's messy to do it for all three platforms) |
340 |
CheckOpenGL() |
341 |
|
342 |
#Check if FFMPEG was enabled |
343 |
CheckFFMPEG(conf, sources) |
344 |
|
345 |
#Platform-specific checks for Linux and Win32... |
346 |
if platform == 'linux' or platform == 'win32': |
347 |
#Check for libsndfile |
348 |
#if not conf.CheckLibWithHeader(['sndfile', 'libsndfile'], 'sndfile.h', 'C'): |
349 |
if not conf.CheckLib(['sndfile', 'libsndfile']): |
350 |
print "Did not find libsndfile or it\'s development headers, exiting!" |
351 |
Exit(1) |
352 |
else: |
353 |
env.Append(CXXFLAGS = ' -D__SNDFILE__') |
354 |
sources.append('soundsourcesndfile.cpp') ## TODO: Convert this to a SharedLibrary, so it can be installed without having to run scons twice after a clean |
355 |
# libsndfile = env.SharedLibrary( |
356 |
# "libsndfile", |
357 |
# source=["soundsourcesndfile.cpp", "trackinfoobject.cpp"]) |
358 |
|
359 |
#Platform-specific checks for Linux... |
360 |
if platform == 'linux': |
361 |
#Check for g++ (yeah, SCONS is a bit dumb here) |
362 |
if os.system("which g++ > /dev/null"): #Checks for non-zero return code |
363 |
print "Did not find gcc/g++, exiting!" |
364 |
Exit(1) |
365 |
|
366 |
#Check for pkg-config |
367 |
if not conf.CheckForPKGConfig('0.15.0'): |
368 |
print 'pkg-config >= 0.15.0 not found.' |
369 |
Exit(1) |
370 |
|
371 |
#Check for QT >= 4.3 |
372 |
if not conf.CheckForPKG('QtCore', '4.3'): |
373 |
print 'QT >= 4.3 not found.' |
374 |
Exit(1) |
375 |
else: |
376 |
#Grabs the QT4 include paths |
377 |
env.ParseConfig('pkg-config QtCore --silence-errors --cflags --libs') |
378 |
env.ParseConfig('pkg-config Qt3Support --silence-errors --cflags') #QT3 support breaks the build |
379 |
env.ParseConfig('pkg-config QtGui --silence-errors --cflags --libs') |
380 |
env.ParseConfig('pkg-config QtXml --silence-errors --cflags --libs') |
381 |
env.ParseConfig('pkg-config QtOpenGL --silence-errors --cflags --libs') |
382 |
# Might be missing $QTDIR/include/Qt still... |
383 |
|
384 |
#Check for libasound (libasound2?) (needed for ALSA seq MIDI support) |
385 |
if not conf.CheckLib('asound'): |
386 |
print "Did not find libasound (aka. libasound2), exiting!" |
387 |
Exit(1) |
388 |
|
389 |
#Check for libdjconsole, if it was passed as a flag |
390 |
flags_djconsole = getFlags(env, 'djconsole', 0) |
391 |
flags_djconsole_legacy = getFlags(env, 'djconsole_legacy', 0) |
392 |
if int(flags_djconsole): |
393 |
if not conf.CheckLibWithHeader('djconsole', 'libdjconsole/djconsole.h', 'C++'): |
394 |
print "Did not find libdjconsole or it\'s development headers, exiting!" |
395 |
Exit(1) |
396 |
env.ParseConfig('pkg-config libdjconsole --silence-errors --cflags --libs') |
397 |
env.Append(CXXFLAGS = '-D__LIBDJCONSOLE__') |
398 |
elif int(flags_djconsole_legacy): |
399 |
# legacy support can not be enabled if libDJConsole support is enabled via djconsole=1 |
400 |
env.Append(CXXFLAGS = '-D__DJCONSOLE_LEGACY__') |
401 |
|
402 |
#Another check for PortAudio-v19 |
403 |
env.ParseConfig('pkg-config --cflags --libs portaudio-2.0') |
404 |
#If the above line looks like magic, it's because it really is. (Read about ParseConfig, it's nifty) |
405 |
|
406 |
#Platform-specific checks for OS X |
407 |
if platform == 'osx': |
408 |
#Check for libsndfile |
409 |
#if not conf.CheckLibWithHeader(['sndfile', 'libsndfile'], 'sndfile.h', 'C'): |
410 |
if not conf.CheckLib(['sndfile', 'libsndfile']): |
411 |
print "Did not find libsndfile or it\'s development headers, exiting!" |
412 |
Exit(1) |
413 |
else: |
414 |
env.Append(CXXFLAGS = ' -D__SNDFILE__') |
415 |
sources.append('soundsourcesndfile.cpp') ## TODO: Convert this to a SharedLibrary, so it can be installed without having to run scons twice after a clean |
416 |
# libsndfile = env.SharedLibrary( |
417 |
# "libsndfile", |
418 |
# source=["soundsourcesndfile.cpp", "trackinfoobject.cpp"]) |
419 |
|
420 |
#Check for QT4 (framework) |
421 |
"""if not os.path.exists('/Library/Frameworks/QtCore.framework/Versions/4/Headers/QtCore') or : |
422 |
print 'Did not find QT4 framework, going to look for libs instead (use qtdir flag)...' |
423 |
else: |
424 |
env.Append(LINKFLAGS = '-framework QtCore -framework QtOpenGL -framework Qt3Support -framework QtGui -framework QtXml -framework QtNetwork -framework QtSql') |
425 |
env.Append(CXXFLAGS = '-I/Library/Frameworks/QtCore.framework/Headers/') |
426 |
env.Append(CXXFLAGS = '-I/Library/Frameworks/QtOpenGL.framework/Headers/') |
427 |
env.Append(CXXFLAGS = '-I/Library/Frameworks/Qt3Support.framework/Headers/') |
428 |
env.Append(CXXFLAGS = '-I/Library/Frameworks/QtGui.framework/Headers/') |
429 |
env.Append(CXXFLAGS = '-I/Library/Frameworks/QtXml.framework/Headers/') |
430 |
""" |
431 |
#Check for QT libs (rather than framework) |
432 |
if not os.path.exists(flags_qtdir): |
433 |
print 'Did not find QT4 path (qtdir: ' + flags_qtdir + ' not found), exiting!' |
434 |
else: |
435 |
env.Append(LIBPATH=flags_qtdir + '/lib/') |
436 |
env.Append(CPPPATH=flags_qtdir + '/include/') |
437 |
env.Append(LIBS = 'Qt3Support'); |
438 |
env.Append(LIBS = 'QtXml'); |
439 |
env.Append(LIBS = 'QtGui'); |
440 |
env.Append(LIBS = 'QtCore'); |
441 |
env.Append(LIBS = 'QtOpenGL'); |
442 |
env.Append(LIBS = 'QtNetwork'); |
443 |
env.Append(LIBS = 'QtSql'); |
444 |
|
445 |
|
446 |
#Check for CoreMIDI |
447 |
if not conf.CheckCXXHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'): |
448 |
print 'Did not find CoreMIDI framework, exiting! (Please install it)' |
449 |
Exit(1) |
450 |
else: |
451 |
env.Append(LINKFLAGS = '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework Carbon -framework Quicktime -framework AudioToolbox -framework AudioUnit') #Have to add the rest of these frameworks somewhere... |
452 |
|
453 |
|
454 |
env = conf.Finish() |
455 |
|
456 |
|
457 |
#Declare the flags for Mixxx's config/track listing files: |
458 |
if platform == 'linux': |
459 |
env.Append(CXXFLAGS = ' -D__UNIX__ -D__LINUX__ -DBPMSCHEME_FILE=\\".mixxxbpmscheme.xml\\" -DSETTINGS_FILE=\\".mixxx.cfg\\" -DTRACK_FILE=\\".mixxxtrack.xml\\"') |
460 |
env.Append(CXXFLAGS = ' -DUNIX_SHARE_PATH=\\"' + ARGUMENTS.get('prefix', '/usr/local') + '/share/mixxx\\"') |
461 |
elif platform == 'osx': |
462 |
env.Append(CXXFLAGS = ' -D__MACX__ -DBPMSCHEME_FILE=\\".mixxxbpmscheme.xml\\" -DSETTINGS_FILE=\\".mixxx.cfg\\" -DTRACK_FILE=\\".mixxxtrack.xml\\"') |
463 |
elif platform == 'win32': |
464 |
env.Append(CXXFLAGS = '-D__WIN32__ -DBPMSCHEME_FILE=\\"mixxxbpmschemes.xml\\" -DSETTINGS_FILE=\\"mixxx.cfg\\" -DTRACK_FILE=\\"mixxxtrack.xml\\"') |
465 |
|
466 |
#... and yes, we need to double-escape those quotes |
467 |
env.Append(CXXFLAGS = ' -D__PORTAUDIO__'); #Turn on PortAudio support in Mixxx |
468 |
env.Append(CPPPATH = ['.', '../', '../../']) #Fun fun fun with paths |
469 |
|
470 |
|
471 |
if platform == 'linux': |
472 |
env.Append(LIBS = 'Qt3Support'); |
473 |
env.Append(LIBS = 'QtXml'); |
474 |
env.Append(LIBS = 'QtGui'); |
475 |
env.Append(LIBS = 'QtCore'); |
476 |
env.Append(LIBS = 'QtOpenGL'); |
477 |
|
478 |
if platform == 'win32': |
479 |
env.Append(LIBS = 'Qt3Support4'); #Win32 needs this instead of 'Qt3Support' |
480 |
env.Append(LIBS = 'QtXml4'); |
481 |
env.Append(LIBS = 'QtGui4'); |
482 |
env.Append(LIBS = 'QtCore4'); |
483 |
env.Append(LIBS = 'QtOpenGL4'); |
484 |
env.Append(LIBS = 'WinMM'); #Needed for Midi stuff |
485 |
env.Append(LIBS = 'ogg_static') |
486 |
env.Append(LIBS = 'vorbis_static') |
487 |
env.Append(LIBS = 'vorbisfile_static') |
488 |
env.Append(LIBS = 'imm32') |
489 |
env.Append(LIBS = 'wsock32') |
490 |
env.Append(LIBS = 'delayimp') |
491 |
env.Append(LIBS = 'winspool') |
492 |
env.Append(LIBS = 'shell32') |
493 |
|
494 |
env.Append(CXXFLAGS = ' -DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT') #Stolen from Mixxx's build output |
495 |
|
496 |
# Manually add the include paths for win32 and OS X (we use pkg-config on Linux) |
497 |
if not platform == 'linux': |
498 |
env.Append(CXXFLAGS = ' -I$QTDIR/include/Qt3Support -I$QTDIR/include/QtCore -I$QTDIR/include/QtGui -I$QTDIR/include/QtXml -I$QTDIR/include/QtOpenGL -I$QTDIR/include/Qt -I"$VCINSTALLDIR/include/atl"') |
499 |
|
500 |
if not platform == 'win32': |
501 |
env.Append(CCFLAGS = Split(""" -pipe -Wall -W -g -D_REENTRANT """)) # omghax |
502 |
env.Append(LINKFLAGS = Split(""" -pipe -Wall -W -g""")) |
503 |
if platform == 'win32': |
504 |
env.Append(CXXFLAGS = '-DWIN32 -D__WIN__ -DUNICODE -D_WINDOWS') #for soundtouch |
505 |
env.Append(CCFLAGS = '-DWIN32 -D__WIN__ -DUNICODE -D_WINDOWS') #for soundtouch |
506 |
|
507 |
#Uic these guys (they're moc'd automatically after this) - Generates the code for the QT UI forms |
508 |
env.Uic4('dlgpreferencesdlg.ui') |
509 |
env.Uic4('dlgprefsounddlg.ui') |
510 |
env.Uic4('dlgprefmididlg.ui') |
511 |
env.Uic4('dlgprefplaylistdlg.ui') |
512 |
env.Uic4('dlgprefcontrolsdlg.ui') |
513 |
env.Uic4('dlgprefeqdlg.ui') |
514 |
env.Uic4('dlgprefcrossfaderdlg.ui') |
515 |
env.Uic4('dlgprefbpmdlg.ui') |
516 |
env.Uic4('dlgbpmschemedlg.ui') |
517 |
env.Uic4('dlgbpmtapdlg.ui') |
518 |
env.Uic4('dlgprefvinyldlg.ui') |
519 |
env.Uic4('dlgprefrecorddlg.ui') |
520 |
env.Uic4('dlgaboutdlg.ui') |
521 |
|
522 |
#Add the QRC file which compiles in some extra resources (prefs icons, etc.) |
523 |
env.Qrc('mixxx.qrc') |
524 |
sources += Split(""" qrc_mixxx.cc """) |
525 |
|
526 |
if platform == 'win32': |
527 |
env.RES('mixxx.rc') |
528 |
sources += Split(""" mixxx.res """) |
529 |
|
530 |
# Uic4 does not need this --> Add these uic/moc generated files to the list of stuff we need to build: |
531 |
#sources.append(Split("""uic_dlgprefsounddlg.cc moc_dlgprefsounddlg.cc |
532 |
# uic_dlgprefcontrolsdlg.cc moc_dlgprefcontrolsdlg.cc |
533 |
# uic_dlgprefmididlg.cc moc_dlgprefmididlg.cc |
534 |
# uic_dlgprefplaylistdlg.cc moc_dlgprefplaylistdlg.cc |
535 |
# uic_dlgprefmixerdlg.cc moc_dlgprefmixerdlg.cc |
536 |
# uic_dlgprefrecorddlg.cc moc_dlgprefrecorddlg.cc |
537 |
# """)) |
538 |
|
539 |
#More complicated way of doing Uic (gives us control over the filenames, but doesn't really matter...) |
540 |
#env.Uic(target = Split('dlgprefcontrolsdlg.h .ui/dlgprefcontrolsdlg.cpp .moc/dlgprefcontrolsdlg.cpp'), |
541 |
# source = 'dlgprefcontrolsdlg.ui') |
542 |
|
543 |
#Tell SCons to build libraries that are bundled with Mixxx |
544 |
#=================================================== |
545 |
|
546 |
#SoundTouch |
547 |
env.Append(CPPPATH=['../../lib/soundtouch']) #Needed two ../../'s because we're compiling from "src/.obj" |
548 |
sources += Split("""enginebufferscalest.cpp ../../lib/soundtouch/SoundTouch.cpp ../../lib/soundtouch/TDStretch.cpp ../../lib/soundtouch/RateTransposer.cpp ../../lib/soundtouch/AAFilter.cpp ../../lib/soundtouch/FIFOSampleBuffer.cpp ../../lib/soundtouch/FIRFilter.cpp """) |
549 |
if platform == 'win32': |
550 |
sources += Split("""../../lib/soundtouch/cpu_detect_x86_win.cpp ../../lib/soundtouch/mmx_win.cpp ../../lib/soundtouch/sse_win.cpp ../../lib/soundtouch/3dnow_win.cpp""") |
551 |
else: |
552 |
sources += Split("""../../lib/soundtouch/cpu_detect_x86_gcc.cpp""") |
553 |
|
554 |
#KissFFT |
555 |
env.Append(CPPPATH=['../../lib/kissfft']) |
556 |
sources += Split("""../../lib/kissfft/kiss_fft.c""") |
557 |
|
558 |
#libsamplerate |
559 |
env.Append(CPPPATH='../../lib/libsamplerate') |
560 |
sources += Split("""enginebufferscalesrc.cpp ../../lib/libsamplerate/samplerate.c ../../lib/libsamplerate/src_linear.c ../../lib/libsamplerate/src_sinc.c ../../lib/libsamplerate/src_zoh.c""") |
561 |
|
562 |
#fidlib (for EQs) |
563 |
env.Append(CPPPATH='../../lib/fidlib-0.9.9/') |
564 |
sources += Split("""../../lib/fidlib-0.9.9/fidlib.c """) |
565 |
#Platform-specific compile/link flags needed for fidlib |
566 |
if platform == 'linux' or platform == 'osx': |
567 |
env.Append(CCFLAGS = '-DT_LINUX') |
568 |
elif platform == 'win32': |
569 |
env.Append(CCFLAGS = '-DT_MSVC') |
570 |
env.Append(CXXFLAGS = '-DT_MSVC') |
571 |
env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT.lib', '/nodefaultlib:LIBCMTD.lib']) |
572 |
|
573 |
|
574 |
#Parse command-line build flags |
575 |
build_flags = "" |
576 |
|
577 |
print "\nFeatures Summary:\n================" |
578 |
|
579 |
#Python/lua scripting |
580 |
#flags_script = ARGUMENTS.get('script', 0) #Default value is 0 |
581 |
#if int(flags_script): |
582 |
# env.Append(CXXFLAGS = '-D__SCRIPT__ -D__LUA__ -D__PYTHON__') |
583 |
# sources += Split("""script/*.cpp script/lua/*.cpp script/python/*.cpp""") |
584 |
# env.ParseConfig('python-config --include --ldflags') |
585 |
# env.Append(LIBS = 'lua') |
586 |
# env.Append(LIBS = 'lualib') |
587 |
# env.Append(LIBS = 'tulua') |
588 |
# print "Python and Lua scripting... enabled" |
589 |
#else: |
590 |
# print "Python and Lua scripting... disabled" |
591 |
#TODO: FINISH THIS! |
592 |
|
593 |
|
594 |
#Hercules support through libdjconsole on Linux |
595 |
#(handled somewhere else above this in the file... |
596 |
# just printing the summary here) |
597 |
flags_djconsole = getFlags(env, 'djconsole', 0) |
598 |
if int(flags_djconsole) == 0: |
599 |
print "libdjconsole support... disabled" |
600 |
else: |
601 |
print "libdjconsole support... enabled" |
602 |
build_flags += 'djconsole ' |
603 |
|
604 |
#High quality EQs |
605 |
flags_hifieq = getFlags(env, 'hifieq', 1) |
606 |
if int(flags_hifieq) == 0: |
607 |
env.Append(CXXFLAGS = '-D__LOFI__ -D__NO_INTTYPES__') #Enables old crappy EQs |
608 |
print "High quality EQs... disabled" |
609 |
else: |
610 |
print "High quality EQs... enabled" |
611 |
build_flags += 'hifieq ' |
612 |
|
613 |
#Case Metrics |
614 |
flags_cmetrics = getFlags(env, 'cmetrics', 0) |
615 |
if int(flags_cmetrics): |
616 |
env.Append(CXXFLAGS = '-D__C_METRICS__') |
617 |
if platform == 'win32': |
618 |
env.Append(LIBS = 'cmetrics') |
619 |
else: |
620 |
client = 'MIXXX' |
621 |
server = 'casemetrics.net' #NOTE: Permission to use this server is granted only to mixxx, any other use must obtain prior permission |
622 |
Export('env platform client server') |
623 |
env.Append(CPPPATH='../../lib/cmetrics') |
624 |
sources += SConscript('../../lib/cmetrics/SConscript') |
625 |
print "Case Metrics profiling... enabled" |
626 |
build_flags += 'cmetrics ' |
627 |
else: |
628 |
print "Case Metrics profiling... disabled" |
629 |
|
630 |
#Experimental Shoutcast |
631 |
flags_shoutcast = getFlags(env, 'shoutcast', 0) |
632 |
if int(flags_shoutcast): |
633 |
#TODO: check for libshout |
634 |
env.Append(LIBS = 'shout'); |
635 |
env.Append(LIBS = 'vorbisenc'); |
636 |
env.Append(CXXFLAGS = '-D__SHOUTCAST__') |
637 |
sources += Split(""" dlgprefshoutcast.cpp engineshoutcast.cpp encodervorbis.cpp """ ) |
638 |
env.Uic4('dlgprefshoutcastdlg.ui') |
639 |
print "Shoutcast support... enabled" |
640 |
build_flags += 'shoutcast ' |
641 |
else: |
642 |
print "Shoutcast support... disabled" |
643 |
|
644 |
#LADSPA |
645 |
#TODO: Make sure we check for ladspa.h and the library... |
646 |
flags_ladspa = getFlags(env, 'ladspa', 0) |
647 |
if int(flags_ladspa): |
648 |
env.Append(CXXFLAGS = '-D__LADSPA__') |
649 |
sources += Split("""engineladspa.cpp ladspaloader.cpp ladspalibrary.cpp ladspaplugin.cpp ladspainstance.cpp ladspacontrol.cpp ladspainstancestereo.cpp ladspainstancemono.cpp ladspaview.cpp ladspapreset.cpp ladspapresetmanager.cpp ladspapresetknob.cpp ladspapresetinstance.cpp dlgladspa.cpp""") |
650 |
print "LADSPA support... enabled" |
651 |
build_flags += 'ladspa ' |
652 |
else: |
653 |
print "LADSPA support... disabled" |
654 |
|
655 |
#Vinyl Control |
656 |
flags_vinylcontrol = getFlags(env, 'vinylcontrol', 1) |
657 |
if int(flags_vinylcontrol): |
658 |
env.Append(CXXFLAGS = '-D__VINYLCONTROL__') |
659 |
sources += Split(""" vinylcontrol.cpp vinylcontrolproxy.cpp vinylcontrolscratchlib.cpp vinylcontrolxwax.cpp dlgprefvinyl.cpp |
660 |
enginevinylcontrol.cpp """) |
661 |
env.Append(CPPPATH='../../lib/xwax') |
662 |
if platform == 'win32': |
663 |
sources += Split("""../../lib/xwax/timecoder_win32.c """) |
664 |
else: |
665 |
sources += Split("""../../lib/xwax/timecoder.c """) |
666 |
env.Append(CPPPATH='../../lib/scratchlib') |
667 |
sources += Split("""../../lib/scratchlib/DAnalyse.cpp """) |
668 |
print "Vinyl Control... enabled" |
669 |
build_flags += 'vinylcontrol ' |
670 |
else: |
671 |
print "Vinyl Control... disabled" |
672 |
|
673 |
flags_msvcdebug = getFlags(env, 'msvcdebug', 1) |
674 |
if int(flags_msvcdebug) and platform == 'win32': |
675 |
env.Append(LINKFLAGS = '/DEBUG') |
676 |
env.Append(CXXFLAGS = '/ZI') |
677 |
print "MSVC Debugging... enabled" |
678 |
build_flags += 'msvcdebug ' |
679 |
else: |
680 |
print "MSVC Debugging... disabled" |
681 |
|
682 |
flags_script = getFlags(env, 'script', 0) |
683 |
if int(flags_script): |
684 |
if platform == 'win32': |
685 |
env.Append(LIBS = 'QtScript4') |
686 |
else: |
687 |
env.Append(LIBS = 'QtScript') |
688 |
print "SuperCoolAwesomeScript (name contest pending)... enabled" |
689 |
build_flags += 'script ' |
690 |
sources += Split("""script/scriptengine.cpp script/scriptcontrolqueue.cpp |
691 |
script/scriptstudio.cpp script/scriptrecorder.cpp |
692 |
script/playinterface.cpp script/macro.cpp |
693 |
script/scriptcontrolevent.cpp script/trackcontrolevent.cpp |
694 |
script/numbercontrolevent.cpp script/numberrecorder.cpp |
695 |
script/macrolist.cpp script/trackrecorder.cpp |
696 |
script/sdatetime.cpp script/signalrecorder.cpp |
697 |
script/macrolistitem.cpp script/qtscriptinterface.cpp""") |
698 |
env.Append(CXXFLAGS = '-I$QTDIR/include/QtScript') |
699 |
env.Append(CXXFLAGS = '-D__SCRIPT__') |
700 |
|
701 |
env.Uic4('script/scriptstudio.ui') |
702 |
else: |
703 |
flags_script = 0 |
704 |
print "SuperCoolAwesomeScript (name contest pending)... disabled" |
705 |
|
706 |
#Optimization |
707 |
if platform == 'win32': |
708 |
flags_optimize = getFlags(env, 'optimize', 0) #Default to off on win32 |
709 |
else: |
710 |
flags_optimize = getFlags(env, 'optimize', 1) #Default to on for Linux/OS X |
711 |
if int(flags_optimize): |
712 |
if platform == 'win32': |
713 |
if int(flags_msvcdebug): |
714 |
print "Optimizations... DISABLED DUE TO DEBUG" |
715 |
else: |
716 |
print "Optimizations... enabled" |
717 |
env.Append(CXXFLAGS = '/O2 /GL') |
718 |
env.Append(LINKFLAGS = '/LTCG:STATUS') |
719 |
else: |
720 |
print "Optimizations... enabled" |
721 |
build_flags += 'optimize=' + str(flags_optimize) + ' ' |
722 |
if flags_optimize=='1': |
723 |
env.Append(CXXFLAGS = '-O3') |
724 |
elif flags_optimize=='2': |
725 |
print " P4 MMX/SSE optimizations enabled." |
726 |
env.Append(CXXFLAGS = '-O3 -march=pentium4 -mmmx -msse2 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops') |
727 |
elif flags_optimize=='3': |
728 |
print " Intel Core Solo/Duo optimizations enabled." |
729 |
env.Append(CXXFLAGS = '-O3 -march=prescott -mmmx -msse3 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops') |
730 |
elif flags_optimize=='4': |
731 |
print " Intel Core 2 optimizations enabled." |
732 |
env.Append(CXXFLAGS = '-O3 -march=nocona -mmmx -msse3 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops') |
733 |
else: |
734 |
print "Optimizations... disabled" |
735 |
|
736 |
|
737 |
|
738 |
|
739 |
# Profiling and Optimization |
740 |
if not platform == 'win32': |
741 |
flags_gprof = getFlags(env, 'gprof', 0) |
742 |
if int(flags_gprof): |
743 |
env.Append(CCFLAGS = '-pg') |
744 |
env.Append(LINKFLAGS = '-pg') |
745 |
print "gprof profiling support... enabled" |
746 |
build_flags += 'gprof ' |
747 |
else: |
748 |
print "gprof profiling support... disabled" |
749 |
flags_tuned = getFlags(env, 'tuned', 0) |
750 |
if int(flags_tuned): |
751 |
ccv = env['CCVERSION'].split('.') |
752 |
if int(ccv[0]) >= 4 and int(ccv[1]) >= 2: |
753 |
env.Append(CCFLAGS = '-march=native') |
754 |
env.Append(LINKFLAGS = '-march=native') |
755 |
print "Optimizing for this CPU... yes" |
756 |
build_flags += 'tuned ' |
757 |
else: |
758 |
print "Optimizing for this CPU... no (requires gcc >= 4.2.0)" |
759 |
else: |
760 |
print "Optimizing for this CPU... no" |
761 |
|
762 |
#Visual Studio 2005 hacks (MSVS Express Edition users shouldn't enable this) |
763 |
flags_msvshacks = getFlags(env, 'msvshacks', 0) |
764 |
if int(flags_msvshacks): |
765 |
env.Append(CXXFLAGS = '-D__MSVS2005__') |
766 |
print "MSVS 2005 hacks... enabled" |
767 |
build_flags += 'msvshacks ' |
768 |
else: |
769 |
print "MSVS 2005 hacks... disabled" |
770 |
|
771 |
print "================\n" |
772 |
|
773 |
### Put flags info into a file |
774 |
f = open("../.mixxx_flags.svn","w") |
775 |
try: |
776 |
f.write('#define BUILD_FLAGS "' + build_flags + '"\n') |
777 |
finally: |
778 |
f.close() |
779 |
|
780 |
|
781 |
#Save the options to cache |
782 |
opts.Save(cachefile, env) |
783 |
|
784 |
#Tell SCons to build Mixxx |
785 |
#========================= |
786 |
if platform == 'win32': |
787 |
mixxx_bin = env.Program('mixxx', sources, LINKCOM = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1']) |
788 |
else: |
789 |
mixxx_bin = env.Program('mixxx', sources) |
790 |
|
791 |
#Set up the MSVC target to build a Visual Studio project/solution file |
792 |
if 'msvc' in COMMAND_LINE_TARGETS: |
793 |
includes = glob.glob('src/*.h') |
794 |
includes += glob.glob('src/visual/*.h') |
795 |
#Make the project file aware of any command-line arguments that were passed... |
796 |
cmdargs = "" |
797 |
for k in SCons.Script.ARGUMENTS: |
798 |
cmdargs += " " + k + "=" + SCons.Script.ARGUMENTS[k] |
799 |
env.Append(MSVSSCONSFLAGS = cmdargs) |
800 |
#env.Append(MSVSSCONSFLAGS = ' qtdir=' + flags_qtdir) |
801 |
|
802 |
# This is the right way to do it but scons is stupid and doesn't copy flags in... Adam |
803 |
# Set up environment for debug target |
804 |
# TODO Handle lib versions ie /MDd /Md etc... |
805 |
#debugenv = env.Clone() |
806 |
#debugenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:dist/mixxx.pdb']) # Generate MS VC Program Debug Database |
807 |
#debugenv.Append(CXXFLAGS = '/ZI') |
808 |
|
809 |
msvc = env.MSVSProject(target = 'mixxx' + env['MSVSPROJECTSUFFIX'], srcs = flatten(sources), incs = flatten(includes), variant = 'Debug', runfile = '../dist/mixxx') |
810 |
|
811 |
# Reenable this once bug in scons is fixed... |
812 |
#msvc = env.MSVSProject(target = 'mixxx' + env['MSVSPROJECTSUFFIX'], srcs = flatten(sources), incs = flatten(includes), variant = 'Release', runfile = '../dist/mixxx') |
813 |
|
814 |
env.Alias('msvc', msvc) |
815 |
|
816 |
#Set up the install target |
817 |
#========================= |
818 |
""" |
819 |
flags_prefix = ARGUMENTS.get('prefix', '/usr/local') |
820 |
if not os.path.exists(flags_prefix): |
821 |
print "Error: Prefix path does not exist!" |
822 |
Exit(1) |
823 |
else: |
824 |
unix_share_path = flags_prefix + "/share" |
825 |
unix_bin_path = flags_prefix + "/bin" |
826 |
""" |
827 |
|
828 |
#Mixxx binary |
829 |
binary_files = mixxx_bin; |
830 |
|
831 |
#Skins |
832 |
skin_files = glob.glob('../skins/*') |
833 |
|
834 |
#MIDI mappings |
835 |
midimappings_files = glob.glob('../midi/*') |
836 |
|
837 |
#Keyboard mapping(s) |
838 |
keyboardmappings_files = glob.glob('../keyboard/*') |
839 |
|
840 |
#Documentation |
841 |
docs_files = glob.glob('../../LICENSE') |
842 |
docs_files += glob.glob('../../README') |
843 |
docs_files += glob.glob('../../Mixxx-Manual.pdf') |
844 |
|
845 |
#.desktop file for KDE/GNOME menu |
846 |
dotdesktop_files = glob.glob('../mixxx.desktop') |
847 |
|
848 |
#Icon file for menu entry |
849 |
icon_files = glob.glob('../mixxx-icon.png') |
850 |
|
851 |
#Images for preferences dialog |
852 |
image_files = glob.glob('../images/preferences/*') # These are compiled in to the "mixxx" binary through mixxx.qrc |
853 |
|
854 |
#Windows DLLs |
855 |
dll_files = glob.glob('../../../mixxx-winlib/*.dll') # TODO: Use reference to SharedLibrary for libsndfile and others, glob only gets all files on 2+ builds after a clean. |
856 |
# dll_files = libsndfile |
857 |
dll_files += Split("""$QTDIR/lib/Qt3Support4.dll $QTDIR/lib/QtCore4.dll $QTDIR/lib/QtGui4.dll $QTDIR/lib/QtNetwork4.dll $QTDIR/lib/QtOpenGL4.dll $QTDIR/lib/QtSql4.dll $QTDIR/lib/QtXml4.dll """) |
858 |
|
859 |
if int(flags_script): |
860 |
dll_files += Split("""$QTDIR/lib/QtScript4.dll""") |
861 |
|
862 |
if platform == 'linux': |
863 |
flags_prefix = ARGUMENTS.get('prefix', '/usr/local') |
864 |
if not os.path.exists(flags_prefix): |
865 |
print "Error: Prefix path does not exist!" |
866 |
Exit(1) |
867 |
else: |
868 |
#install_root is used in Debian/Ubuntu packaging (check the debian/rules file in the Ubuntu package) |
869 |
#Basically, the flags_prefix is compiled into strings in Mixxx, whereas the install_root is not. When you're |
870 |
#building a Debian package, pbuilder wants to install Mixxx to a temporary directory, but you still need |
871 |
#the compiled-in strings using /usr as the prefix. That's why we have install_root and flags_prefix. |
872 |
install_root = ARGUMENTS.get('install_root', flags_prefix) |
873 |
print "Install root: " + install_root |
874 |
if install_root != flags_prefix: |
875 |
unix_share_path = install_root + "/share" |
876 |
unix_bin_path = install_root + "/bin" |
877 |
else: |
878 |
unix_share_path = flags_prefix + "/share" |
879 |
unix_bin_path = flags_prefix + "/bin" |
880 |
|
881 |
binary = env.Install(unix_bin_path, binary_files) |
882 |
skins = env.Install(unix_share_path + "/mixxx/skins", skin_files) |
883 |
midimappings = env.Install(unix_share_path + "/mixxx/midi", midimappings_files) |
884 |
keyboardmappings = env.Install(unix_share_path + "/mixxx/keyboard", keyboardmappings_files) |
885 |
dotdesktop = env.Install(unix_share_path + "/applications", dotdesktop_files) |
886 |
docs = env.Install(unix_share_path + "/doc/mixxx", docs_files) |
887 |
icon = env.Install(unix_share_path + "/pixmaps", icon_files) |
888 |
|
889 |
#Makes each of those Install builders get fired off when you run "scons install" :) |
890 |
env.Alias('install', binary) |
891 |
env.Alias('install', skins) |
892 |
env.Alias('install', midimappings) |
893 |
env.Alias('install', keyboardmappings) |
894 |
env.Alias('install', docs) |
895 |
env.Alias('install', dotdesktop) |
896 |
env.Alias('install', icon) |
897 |
|
898 |
#Delete the old Mixxx installation (because SCONS won't overwrite it) |
899 |
#if 'install' in COMMAND_LINE_TARGETS: |
900 |
#os.system('scons -c install') |
901 |
#Delete(unix_share_path + "/mixxx/skins") |
902 |
#print "Copying skins..." |
903 |
#env.Command(unix_share_path + "/mixxx/skins", skin_files, Copy("$TARGET", "$SOURCE"), source_scanner = DirScanner) |
904 |
#Copy(unix_share_path + "/.ixxx/skins", skin_files) |
905 |
#Delete(unix_bin_path + "mixxx") |
906 |
|
907 |
#Delete(unix_share_path + "/mixxx/midi") |
908 |
#Delete(unix_share_path + "/mixxx/keyboard") |
909 |
|
910 |
#Build the Mixxx.app directory |
911 |
if platform == 'osx': |
912 |
|
913 |
#Files needed to create the OS X package |
914 |
osx_plist_file = glob.glob('../osx/Info.plist') |
915 |
osx_pkginfo_file = glob.glob('../osx/PkgInfo') |
916 |
osx_icns_file = glob.glob('../osx/application.icns') |
917 |
|
918 |
osx_dist_path = "../../Mixxx.app" |
919 |
osx_share_path = osx_dist_path |
920 |
binary = env.Install(osx_dist_path + "/Contents/MacOS", binary_files) |
921 |
skins = env.Install(osx_dist_path + "/skins", skin_files) |
922 |
midimappings = env.Install(osx_dist_path + "/midi", midimappings_files) |
923 |
keyboardmappings = env.Install(osx_dist_path + "/keyboard", keyboardmappings_files) |
924 |
docs = env.Install(osx_dist_path + "/doc", docs_files) |
925 |
osx_plist = env.Install(osx_dist_path + "/Contents", osx_plist_file) |
926 |
osx_pkginfo = env.Install(osx_dist_path + "/Contents", osx_pkginfo_file) |
927 |
osx_icns = env.Install(osx_dist_path + "/Contents/Resources", osx_icns_file) |
928 |
|
929 |
|
930 |
#Makes each of those Install builders get fired off when you run "scons install" :) |
931 |
env.Alias('install', binary) |
932 |
env.Alias('install', skins) |
933 |
env.Alias('install', midimappings) |
934 |
env.Alias('install', keyboardmappings) |
935 |
env.Alias('install', osx_plist) |
936 |
env.Alias('install', osx_pkginfo) |
937 |
env.Alias('install', osx_icns) |
938 |
|
939 |
|
940 |
if platform == 'win32': |
941 |
skins = env.Install("../../dist/skins", skin_files) |
942 |
midimappings = env.Install("../../dist/midi", midimappings_files) |
943 |
keyboardmappings = env.Install("../../dist/keyboard", keyboardmappings_files) |
944 |
docs = env.Install("../../dist/doc/", docs_files) |
945 |
#icon = env.Install("../../dist", icon_files) |
946 |
dlls = env.Install("../../dist/", dll_files) |
947 |
binary = env.Install("../../dist/", binary_files) |
948 |
|
949 |
#Always trigger these install builders when compiling on Windows |
950 |
env.Alias('mixxx', skins) |
951 |
env.Alias('mixxx', midimappings) |
952 |
env.Alias('mixxx', keyboardmappings) |
953 |
env.Alias('mixxx', docs) |
954 |
env.Alias('mixxx', dlls) |
955 |
#env.Alias('mixxx', icon) |
956 |
env.Alias('mixxx', binary) |
957 |
|
958 |
|
959 |
|
960 |
def BuildRelease(target, source, env): |
961 |
print |
962 |
print "==== Mixxx Post-Build Checks ====" |
963 |
print |
964 |
print "You have built version ", |
965 |
os.system('grep -m 1 VERSION src/defs.h | cut -d \' \' -f 3') |
966 |
print |
967 |
print "Binary has size ", |
968 |
os.system('ls -lh dist/mixxx.exe | cut -d \' \' -f 5') |
969 |
print |
970 |
print "Installer file ", |
971 |
os.system('grep OutFile Mixxx.nsi | cut -d \' \' -f 2') |
972 |
print |
973 |
print "Top line of README, check version:" |
974 |
os.system('head -n 1 README') |
975 |
print |
976 |
print "Top 2 lines of LICENSE, check version and copyright dates:" |
977 |
os.system('head -n 2 LICENSE') |
978 |
print |
979 |
print "More checks here soon... :)" |
980 |
print |
981 |
|
982 |
if (raw_input("Go ahead and build installer (yes/[no])? ") == "yes"): |
983 |
print "Now building installer..." |
984 |
os.system('"c:/Program Files/NSIS/makensis.exe" Mixxx.nsi') |
985 |
else: |
986 |
print "Aborted building installer" |
987 |
|
988 |
# Do release things |
989 |
versionbld = Builder(action = BuildRelease, suffix = '.foo', src_suffix = '.bar') |
990 |
env.Append(BUILDERS = {'BuildRelease' : versionbld}) |
991 |
|
992 |
if 'makerelease' in COMMAND_LINE_TARGETS: |
993 |
makerelease = env.BuildRelease('', binary_files) |
994 |
env.Alias('makerelease', makerelease) |
995 |
|
996 |
#Build the Ubuntu package |
997 |
def BuildUbuntuPackage(target, source, env): |
998 |
print |
999 |
print "==== Mixxx Post-Build Checks ====" |
1000 |
print |
1001 |
print "You have built version ", |
1002 |
p = os.popen('grep -m 1 VERSION src/defs.h | cut -d \' \' -f 3 | tr -d \'\"\' | tr -d \'\n\'') |
1003 |
version = p.readline() |
1004 |
p.close() |
1005 |
print |
1006 |
print |
1007 |
print "Top line of README, check version:" |
1008 |
os.system('head -n 1 README') |
1009 |
print |
1010 |
print "Top 2 lines of LICENSE, check version and copyright dates:" |
1011 |
os.system('head -n 2 LICENSE') |
1012 |
print |
1013 |
print "Top line of debian/ubuntu changelog, check version:" |
1014 |
os.system('head -n 1 src/debian/changelog') |
1015 |
print |
1016 |
|
1017 |
if ("yes" == "yes"): |
1018 |
print "Now building DEB package..." |
1019 |
|
1020 |
mixxx_dir = 'mixxx-' + version |
1021 |
mixxx_tarball = 'mixxx_' + version + '.orig.tar.gz' #The underscore is super important here |
1022 |
#to make the deb package work |
1023 |
|
1024 |
if not os.path.exists('ubuntu'): |
1025 |
os.mkdir('ubuntu') |
1026 |
print "Exporting source tree from HEAD" |
1027 |
|
1028 |
os.system('svn export --force -rHEAD . ubuntu/mixxx-' + version) |
1029 |
|
1030 |
os.chdir('ubuntu') |
1031 |
|
1032 |
#Temporarily move the debian directory out of the source directory |
1033 |
#because it can't be included in the source tarball (which we create next). |
1034 |
#print "Moving debian directory" |
1035 |
#os.system('rm -f debian') |
1036 |
#os.system('mv mixxx-' + version + '/src/debian .') |
1037 |
|
1038 |
print "Tarring source directory..." |
1039 |
os.system("rm -f mixxx_" + version + ".orig.tar.gz") #Remove old tarball |
1040 |
os.system('tar --exclude=debian --exclude=debian/* -cvzf mixxx_' + version + '.orig.tar.gz ' + mixxx_dir) |
1041 |
|
1042 |
#Move the debian directory into the right spot. |
1043 |
#os.system('mv debian mixxx-' + version) |
1044 |
os.system('rm -rf ' + mixxx_dir + '/debian') |
1045 |
os.system('mv ' + mixxx_dir + '/src/debian ' + mixxx_dir) |
1046 |
|
1047 |
#Run pbuilder |
1048 |
os.chdir(mixxx_dir) |
1049 |
os.system('pdebuild') |
1050 |
|
1051 |
#/var/cache/pbuilder/result |
1052 |
print |
1053 |
print "Signing the .deb changes file..." |
1054 |
os.system('sudo debsign /var/cache/pbuilder/result/*.changes') |
1055 |
|
1056 |
print "Done! Package and tarballs are in /var/cache/pbuilder/result" |
1057 |
|
1058 |
else: |
1059 |
print "Aborted building installer" |
1060 |
|
1061 |
#Build the Ubuntu package if "makeubuntu" was passed as an argument |
1062 |
versiondebbld = Builder(action = BuildUbuntuPackage, suffix = '.foo', src_suffix = '.bar') |
1063 |
env.Append(BUILDERS = {'BuildUbuntuPackage' : versiondebbld}) |
1064 |
|
1065 |
if 'makeubuntu' in COMMAND_LINE_TARGETS: |
1066 |
makeubuntu = env.BuildUbuntuPackage('', binary_files) |
1067 |
env.Alias('makeubuntu', makeubuntu) |