annotate src/portaudio_20161030_catalina_patch/SConstruct @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 4edcd14160a5
children
rev   line source
Chris@4 1 import sys, os.path
Chris@4 2
Chris@4 3 def rsplit(toSplit, sub, max=-1):
Chris@4 4 """ str.rsplit seems to have been introduced in 2.4 :( """
Chris@4 5 l = []
Chris@4 6 i = 0
Chris@4 7 while i != max:
Chris@4 8 try: idx = toSplit.rindex(sub)
Chris@4 9 except ValueError: break
Chris@4 10
Chris@4 11 toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):]
Chris@4 12 l.insert(0, splitOff)
Chris@4 13 i += 1
Chris@4 14
Chris@4 15 l.insert(0, toSplit)
Chris@4 16 return l
Chris@4 17
Chris@4 18 sconsDir = os.path.join("build", "scons")
Chris@4 19 SConscript(os.path.join(sconsDir, "SConscript_common"))
Chris@4 20 Import("Platform", "Posix", "ApiVer")
Chris@4 21
Chris@4 22 # SConscript_opts exports PortAudio options
Chris@4 23 optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts"))
Chris@4 24 optionsCache = os.path.join(sconsDir, "options.cache") # Save options between runs in this cache
Chris@4 25 options = Options(optionsCache, args=ARGUMENTS)
Chris@4 26 for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"):
Chris@4 27 options.AddOptions(*optsDict[k])
Chris@4 28 # Propagate options into environment
Chris@4 29 env = Environment(options=options)
Chris@4 30 # Save options for next run
Chris@4 31 options.Save(optionsCache, env)
Chris@4 32 # Generate help text for options
Chris@4 33 env.Help(options.GenerateHelpText(env))
Chris@4 34
Chris@4 35 buildDir = os.path.join("#", sconsDir, env["PLATFORM"])
Chris@4 36
Chris@4 37 # Determine parameters to build tools
Chris@4 38 if Platform in Posix:
Chris@4 39 threadCFlags = ''
Chris@4 40 if Platform != 'darwin':
Chris@4 41 threadCFlags = "-pthread "
Chris@4 42 baseLinkFlags = threadCFlags
Chris@4 43 baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags
Chris@4 44 debugCxxFlags = debugCFlags = "-g"
Chris@4 45 optCxxFlags = optCFlags = "-O2"
Chris@4 46 env.Append(CCFLAGS = baseCFlags)
Chris@4 47 env.Append(CXXFLAGS = baseCxxFlags)
Chris@4 48 env.Append(LINKFLAGS = baseLinkFlags)
Chris@4 49 if env["enableDebug"]:
Chris@4 50 env.AppendUnique(CCFLAGS=debugCFlags.split())
Chris@4 51 env.AppendUnique(CXXFLAGS=debugCxxFlags.split())
Chris@4 52 if env["enableOptimize"]:
Chris@4 53 env.AppendUnique(CCFLAGS=optCFlags.split())
Chris@4 54 env.AppendUnique(CXXFLAGS=optCxxFlags.split())
Chris@4 55 if not env["enableAsserts"]:
Chris@4 56 env.AppendUnique(CPPDEFINES=["-DNDEBUG"])
Chris@4 57 if env["customCFlags"]:
Chris@4 58 env.Append(CCFLAGS=Split(env["customCFlags"]))
Chris@4 59 if env["customCxxFlags"]:
Chris@4 60 env.Append(CXXFLAGS=Split(env["customCxxFlags"]))
Chris@4 61 if env["customLinkFlags"]:
Chris@4 62 env.Append(LINKFLAGS=Split(env["customLinkFlags"]))
Chris@4 63
Chris@4 64 env.Append(CPPPATH=[os.path.join("#", "include"), "common"])
Chris@4 65
Chris@4 66 # Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
Chris@4 67 env.SConsignFile(os.path.join(sconsDir, ".sconsign"))
Chris@4 68
Chris@4 69 env.SConscriptChdir(False)
Chris@4 70 sources, sharedLib, staticLib, tests, portEnv, hostApis = env.SConscript(os.path.join("src", "SConscript"),
Chris@4 71 build_dir=buildDir, duplicate=False, exports=["env"])
Chris@4 72
Chris@4 73 if Platform in Posix:
Chris@4 74 prefix = env["prefix"]
Chris@4 75 includeDir = os.path.join(prefix, "include")
Chris@4 76 libDir = os.path.join(prefix, "lib")
Chris@4 77 env.Alias("install", includeDir)
Chris@4 78 env.Alias("install", libDir)
Chris@4 79
Chris@4 80 # pkg-config
Chris@4 81
Chris@4 82 def installPkgconfig(env, target, source):
Chris@4 83 tgt = str(target[0])
Chris@4 84 src = str(source[0])
Chris@4 85 f = open(src)
Chris@4 86 try: txt = f.read()
Chris@4 87 finally: f.close()
Chris@4 88 txt = txt.replace("@prefix@", prefix)
Chris@4 89 txt = txt.replace("@exec_prefix@", prefix)
Chris@4 90 txt = txt.replace("@libdir@", libDir)
Chris@4 91 txt = txt.replace("@includedir@", includeDir)
Chris@4 92 txt = txt.replace("@LIBS@", " ".join(["-l%s" % l for l in portEnv["LIBS"]]))
Chris@4 93 txt = txt.replace("@THREAD_CFLAGS@", threadCFlags)
Chris@4 94
Chris@4 95 f = open(tgt, "w")
Chris@4 96 try: f.write(txt)
Chris@4 97 finally: f.close()
Chris@4 98
Chris@4 99 pkgconfigTgt = "portaudio-%d.0.pc" % int(ApiVer.split(".", 1)[0])
Chris@4 100 env.Command(os.path.join(libDir, "pkgconfig", pkgconfigTgt),
Chris@4 101 os.path.join("#", pkgconfigTgt + ".in"), installPkgconfig)
Chris@4 102
Chris@4 103 # Default to None, since if the user disables all targets and no Default is set, all targets
Chris@4 104 # are built by default
Chris@4 105 env.Default(None)
Chris@4 106 if env["enableTests"]:
Chris@4 107 env.Default(tests)
Chris@4 108 if env["enableShared"]:
Chris@4 109 env.Default(sharedLib)
Chris@4 110
Chris@4 111 if Platform in Posix:
Chris@4 112 def symlink(env, target, source):
Chris@4 113 trgt = str(target[0])
Chris@4 114 src = str(source[0])
Chris@4 115
Chris@4 116 if os.path.islink(trgt) or os.path.exists(trgt):
Chris@4 117 os.remove(trgt)
Chris@4 118 os.symlink(os.path.basename(src), trgt)
Chris@4 119
Chris@4 120 major, minor, micro = [int(c) for c in ApiVer.split(".")]
Chris@4 121
Chris@4 122 soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer)
Chris@4 123 env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib)
Chris@4 124 # Install symlinks
Chris@4 125 symTrgt = os.path.join(libDir, soFile)
Chris@4 126 env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)),
Chris@4 127 symTrgt, symlink)
Chris@4 128 symTrgt = rsplit(symTrgt, ".", 1)[0]
Chris@4 129 env.Command(os.path.join(libDir, "libportaudio.so.%d" % major), symTrgt, symlink)
Chris@4 130 symTrgt = rsplit(symTrgt, ".", 1)[0]
Chris@4 131 env.Command(os.path.join(libDir, "libportaudio.so"), symTrgt, symlink)
Chris@4 132
Chris@4 133 if env["enableStatic"]:
Chris@4 134 env.Default(staticLib)
Chris@4 135 env.Install(libDir, staticLib)
Chris@4 136
Chris@4 137 env.Install(includeDir, os.path.join("include", "portaudio.h"))
Chris@4 138
Chris@4 139
Chris@4 140 if env["enableCxx"]:
Chris@4 141 env.SConscriptChdir(True)
Chris@4 142 cxxEnv = env.Copy()
Chris@4 143 sharedLibs, staticLibs, headers = env.SConscript(os.path.join("bindings", "cpp", "SConscript"),
Chris@4 144 exports={"env": cxxEnv, "buildDir": buildDir}, build_dir=os.path.join(buildDir, "portaudiocpp"), duplicate=False)
Chris@4 145 if env["enableStatic"]:
Chris@4 146 env.Default(staticLibs)
Chris@4 147 env.Install(libDir, staticLibs)
Chris@4 148 if env["enableShared"]:
Chris@4 149 env.Default(sharedLibs)
Chris@4 150 env.Install(libDir, sharedLibs)
Chris@4 151 env.Install(os.path.join(includeDir, "portaudiocpp"), headers)
Chris@4 152
Chris@4 153 # Generate portaudio_config.h header with compile-time definitions of which PA
Chris@4 154 # back-ends are available, and which includes back-end extension headers
Chris@4 155
Chris@4 156 # Host-specific headers
Chris@4 157 hostApiHeaders = {"ALSA": "pa_linux_alsa.h",
Chris@4 158 "ASIO": "pa_asio.h",
Chris@4 159 "COREAUDIO": "pa_mac_core.h",
Chris@4 160 "JACK": "pa_jack.h",
Chris@4 161 "WMME": "pa_winwmme.h",
Chris@4 162 }
Chris@4 163
Chris@4 164 def buildConfigH(target, source, env):
Chris@4 165 """builder for portaudio_config.h"""
Chris@4 166 global hostApiHeaders, hostApis
Chris@4 167 out = ""
Chris@4 168 for hostApi in hostApis:
Chris@4 169 out += "#define PA_HAVE_%s\n" % hostApi
Chris@4 170
Chris@4 171 hostApiSpecificHeader = hostApiHeaders.get(hostApi, None)
Chris@4 172 if hostApiSpecificHeader:
Chris@4 173 out += "#include \"%s\"\n" % hostApiSpecificHeader
Chris@4 174
Chris@4 175 out += "\n"
Chris@4 176 # Strip the last newline
Chris@4 177 if out and out[-1] == "\n":
Chris@4 178 out = out[:-1]
Chris@4 179
Chris@4 180 f = file(str(target[0]), 'w')
Chris@4 181 try: f.write(out)
Chris@4 182 finally: f.close()
Chris@4 183 return 0
Chris@4 184
Chris@4 185 # Define the builder for the config header
Chris@4 186 env.Append(BUILDERS={"portaudioConfig": env.Builder(
Chris@4 187 action=Action(buildConfigH), target_factory=env.fs.File)})
Chris@4 188
Chris@4 189 confH = env.portaudioConfig(File("portaudio_config.h", "include"),
Chris@4 190 File("portaudio.h", "include"))
Chris@4 191 env.Default(confH)
Chris@4 192 env.Install(os.path.join(includeDir, "portaudio"), confH)
Chris@4 193
Chris@4 194 for api in hostApis:
Chris@4 195 if api in hostApiHeaders:
Chris@4 196 env.Install(os.path.join(includeDir, "portaudio"),
Chris@4 197 File(hostApiHeaders[api], "include"))