1import sys, os.path 2 3def rsplit(toSplit, sub, max=-1): 4 """ str.rsplit seems to have been introduced in 2.4 :( """ 5 l = [] 6 i = 0 7 while i != max: 8 try: idx = toSplit.rindex(sub) 9 except ValueError: break 10 11 toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):] 12 l.insert(0, splitOff) 13 i += 1 14 15 l.insert(0, toSplit) 16 return l 17 18sconsDir = os.path.join("build", "scons") 19SConscript(os.path.join(sconsDir, "SConscript_common")) 20Import("Platform", "Posix", "ApiVer") 21 22# SConscript_opts exports PortAudio options 23optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts")) 24optionsCache = os.path.join(sconsDir, "options.cache") # Save options between runs in this cache 25options = Options(optionsCache, args=ARGUMENTS) 26for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"): 27 options.AddOptions(*optsDict[k]) 28# Propagate options into environment 29env = Environment(options=options) 30# Save options for next run 31options.Save(optionsCache, env) 32# Generate help text for options 33env.Help(options.GenerateHelpText(env)) 34 35buildDir = os.path.join("#", sconsDir, env["PLATFORM"]) 36 37# Determine parameters to build tools 38if Platform in Posix: 39 baseLinkFlags = threadCFlags = "-pthread" 40 baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags 41 debugCxxFlags = debugCFlags = "-g" 42 optCxxFlags = optCFlags = "-O2" 43env["CCFLAGS"] = baseCFlags.split() 44env["CXXFLAGS"] = baseCxxFlags.split() 45env["LINKFLAGS"] = baseLinkFlags.split() 46if env["enableDebug"]: 47 env.AppendUnique(CCFLAGS=debugCFlags.split()) 48 env.AppendUnique(CXXFLAGS=debugCxxFlags.split()) 49if env["enableOptimize"]: 50 env.AppendUnique(CCFLAGS=optCFlags.split()) 51 env.AppendUnique(CXXFLAGS=optCxxFlags.split()) 52if not env["enableAsserts"]: 53 env.AppendUnique(CPPDEFINES=["-DNDEBUG"]) 54if env["customCFlags"]: 55 env.Append(CCFLAGS=env["customCFlags"]) 56if env["customCxxFlags"]: 57 env.Append(CXXFLAGS=env["customCxxFlags"]) 58if env["customLinkFlags"]: 59 env.Append(LINKFLAGS=env["customLinkFlags"]) 60 61env.Append(CPPPATH=[os.path.join("#", "include"), "common"]) 62 63# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files 64env.SConsignFile(os.path.join(sconsDir, ".sconsign")) 65 66env.SConscriptChdir(False) 67sources, sharedLib, staticLib, tests, portEnv = env.SConscript(os.path.join("src", "SConscript"), 68 build_dir=buildDir, duplicate=False, exports=["env"]) 69 70if Platform in Posix: 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) 76 77 # pkg-config 78 79 def installPkgconfig(env, target, source): 80 tgt = str(target[0]) 81 src = str(source[0]) 82 f = open(src) 83 try: txt = f.read() 84 finally: f.close() 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) 91 92 f = open(tgt, "w") 93 try: f.write(txt) 94 finally: f.close() 95 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) 99 100# Default to None, since if the user disables all targets and no Default is set, all targets 101# are built by default 102env.Default(None) 103if env["enableTests"]: 104 env.Default(tests) 105if env["enableShared"]: 106 env.Default(sharedLib) 107 108 if Platform in Posix: 109 def symlink(env, target, source): 110 trgt = str(target[0]) 111 src = str(source[0]) 112 113 if os.path.islink(trgt) or os.path.exists(trgt): 114 os.remove(trgt) 115 os.symlink(os.path.basename(src), trgt) 116 117 major, minor, micro = [int(c) for c in ApiVer.split(".")] 118 119 soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer) 120 env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib) 121 # Install symlinks 122 symTrgt = os.path.join(libDir, soFile) 123 env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)), 124 symTrgt, symlink) 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) 129 130if env["enableStatic"]: 131 env.Default(staticLib) 132 env.Install(libDir, staticLib) 133 134env.Install(includeDir, os.path.join("include", "portaudio.h")) 135 136if env["enableCxx"]: 137 env.SConscriptChdir(True) 138 cxxEnv = env.Copy() 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) 148