3
class ConfigurationError(Exception):
4
def __init__(self, reason):
5
Exception.__init__(self, "Configuration failed: %s" % reason)
7
def _PackageOption(pkgName, default="yes"):
8
return BoolOption("use%s" % pkgName[0].upper() + pkgName[1:], "use %s if available" % (pkgName), default)
10
def _BoolOption(opt, explanation, default="yes"):
11
return BoolOption("enable%s" % opt[0].upper() + opt[1:], explanation, default)
13
def _DirectoryOption(path, help, default):
14
return PathOption(path, help, default)
15
# Incompatible with the latest stable SCons
16
# return PathOption(path, help, default, PathOption.PathIsDir)
18
def _EnumOption(opt, explanation, allowedValues, default):
19
assert default in allowedValues
20
return EnumOption("with%s" % opt[0].upper() + opt[1:], explanation, default, allowed_values=allowedValues)
24
try: return __platform
27
if env["PLATFORM"] == "posix":
28
if sys.platform[:5] == "linux":
31
raise ConfigurationError("Unknown platform %s" % sys.platform)
33
if not env["PLATFORM"] in ("win32", "cygwin") + Posix:
34
raise ConfigurationError("Unknown platform %s" % env["PLATFORM"])
35
__platform = env["PLATFORM"]
39
# sunos, aix, hpux, irix, sunos appear to be platforms known by SCons, assuming they're POSIX compliant
40
Posix = ("linux", "darwin", "sunos", "aix", "hpux", "irix", "sunos")
41
Windows = ("win32", "cygwin")
42
env = Environment(CPPPATH="pa_common")
44
Platform = getPlatform()
46
opts = Options("options.cache", args=ARGUMENTS)
3
def rsplit(toSplit, sub, max=-1):
4
""" str.rsplit seems to have been introduced in 2.4 :( """
8
try: idx = toSplit.rindex(sub)
9
except ValueError: break
11
toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):]
18
sconsDir = os.path.join("build", "scons")
19
SConscript(os.path.join(sconsDir, "SConscript_common"))
20
Import("Platform", "Posix", "ApiVer")
22
# SConscript_opts exports PortAudio options
23
optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts"))
24
optionsCache = os.path.join(sconsDir, "options.cache") # Save options between runs in this cache
25
options = Options(optionsCache, args=ARGUMENTS)
26
for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"):
27
options.AddOptions(*optsDict[k])
28
# Propagate options into environment
29
env = Environment(options=options)
30
# Save options for next run
31
options.Save(optionsCache, env)
32
# Generate help text for options
33
env.Help(options.GenerateHelpText(env))
35
buildDir = os.path.join("#", sconsDir, env["PLATFORM"])
37
# Determine parameters to build tools
47
38
if Platform in Posix:
49
_DirectoryOption("prefix", "installation prefix", "/usr/local"),
50
_PackageOption("ALSA"),
51
_PackageOption("OSS"),
52
_PackageOption("JACK"),
54
elif Platform in Windows:
55
if Platform == "cygwin":
56
opts.AddOptions(_DirectoryOption("prefix", "installation prefix", "/usr/local"))
57
opts.AddOptions(_EnumOption("winAPI", "Windows API to use", ("wmme", "directx", "asio"), "wmme"))
59
if Platform == "darwin":
60
opts.AddOptions(_EnumOption("macAPI", "Mac API to use", ("asio", "core", "sm"), "core"))
63
_BoolOption("shared", "create shared library"),
64
_BoolOption("static", "create static library"),
65
_BoolOption("debug", "compile with debug symbols"),
66
_BoolOption("optimize", "compile with optimization", default="no"),
67
_BoolOption("asserts", "runtime assertions are helpful for debugging, but can be detrimental to performance", default="yes"),
68
_BoolOption("debugOutput", "enable debug output", default="no"),
69
("customCFlags", "customize compilation of C code", ""),
73
opts.Save("options.cache", env)
75
Help(opts.GenerateHelpText(env))
39
baseLinkFlags = threadCFlags = "-pthread"
40
baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags
41
debugCxxFlags = debugCFlags = "-g"
42
optCxxFlags = optCFlags = "-O2"
43
env["CCFLAGS"] = baseCFlags.split()
44
env["CXXFLAGS"] = baseCxxFlags.split()
45
env["LINKFLAGS"] = baseLinkFlags.split()
46
if env["enableDebug"]:
47
env.AppendUnique(CCFLAGS=debugCFlags.split())
48
env.AppendUnique(CXXFLAGS=debugCxxFlags.split())
49
if env["enableOptimize"]:
50
env.AppendUnique(CCFLAGS=optCFlags.split())
51
env.AppendUnique(CXXFLAGS=optCxxFlags.split())
52
if not env["enableAsserts"]:
53
env.AppendUnique(CPPDEFINES=["-DNDEBUG"])
54
if env["customCFlags"]:
55
env.Append(CCFLAGS=env["customCFlags"])
56
if env["customCxxFlags"]:
57
env.Append(CXXFLAGS=env["customCxxFlags"])
58
if env["customLinkFlags"]:
59
env.Append(LINKFLAGS=env["customLinkFlags"])
61
env.Append(CPPPATH=[os.path.join("#", "include"), "common"])
63
# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
64
env.SConsignFile(os.path.join(sconsDir, ".sconsign"))
77
66
env.SConscriptChdir(False)
78
SConscript("SConscript", build_dir=".build_scons", exports=["env", "Platform", "Posix", "ConfigurationError"], duplicate=False)
67
sources, sharedLib, staticLib, tests, portEnv = env.SConscript(os.path.join("src", "SConscript"),
68
build_dir=buildDir, duplicate=False, exports=["env"])
71
prefix = env["prefix"]
72
includeDir = os.path.join(prefix, "include")
73
libDir = os.path.join(prefix, "lib")
74
env.Alias("install", includeDir)
75
env.Alias("install", libDir)
79
def installPkgconfig(env, target, source):
85
txt = txt.replace("@prefix@", prefix)
86
txt = txt.replace("@exec_prefix@", prefix)
87
txt = txt.replace("@libdir@", libDir)
88
txt = txt.replace("@includedir@", includeDir)
89
txt = txt.replace("@LIBS@", " ".join(["-l%s" % l for l in portEnv["LIBS"]]))
90
txt = txt.replace("@THREAD_CFLAGS@", threadCFlags)
96
pkgconfigTgt = "portaudio-%d.0.pc" % int(ApiVer.split(".", 1)[0])
97
env.Command(os.path.join(libDir, "pkgconfig", pkgconfigTgt),
98
os.path.join("#", pkgconfigTgt + ".in"), installPkgconfig)
100
# Default to None, since if the user disables all targets and no Default is set, all targets
101
# are built by default
103
if env["enableTests"]:
105
if env["enableShared"]:
106
env.Default(sharedLib)
108
if Platform in Posix:
109
def symlink(env, target, source):
110
trgt = str(target[0])
113
if os.path.islink(trgt) or os.path.exists(trgt):
115
os.symlink(os.path.basename(src), trgt)
117
major, minor, micro = [int(c) for c in ApiVer.split(".")]
119
soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer)
120
env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib)
122
symTrgt = os.path.join(libDir, soFile)
123
env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)),
125
symTrgt = rsplit(symTrgt, ".", 1)[0]
126
env.Command(os.path.join(libDir, "libportaudio.so.%d" % major), symTrgt, symlink)
127
symTrgt = rsplit(symTrgt, ".", 1)[0]
128
env.Command(os.path.join(libDir, "libportaudio.so"), symTrgt, symlink)
130
if env["enableStatic"]:
131
env.Default(staticLib)
132
env.Install(libDir, staticLib)
134
env.Install(includeDir, os.path.join("include", "portaudio.h"))
137
env.SConscriptChdir(True)
139
sharedLibs, staticLibs, headers = env.SConscript(os.path.join("bindings", "cpp", "SConscript"),
140
exports={"env": cxxEnv, "buildDir": buildDir}, build_dir=os.path.join(buildDir, "portaudiocpp"), duplicate=False)
141
if env["enableStatic"]:
142
env.Default(staticLibs)
143
env.Install(libDir, staticLibs)
144
if env["enableShared"]:
145
env.Default(sharedLibs)
146
env.Install(libDir, sharedLibs)
147
env.Install(os.path.join(includeDir, "portaudiocpp"), headers)