import sys, os sys.path.append(Dir("BuildTools/SCons").abspath) import SCons.SConf ################################################################################ # Build variables ################################################################################ vars = Variables("config.py") vars.Add('ccflags', "Extra C(++) compiler flags") vars.Add('linkflags', "Extra linker flags") vars.Add(EnumVariable("test", "Compile and run tests", "none", ["none", "all", "unit", "system"])) vars.Add(BoolVariable("optimize", "Compile with optimizations turned on", "no")) vars.Add(BoolVariable("debug", "Compile with debug information", "yes" if os.name != "nt" else "no")) vars.Add(BoolVariable("warnings", "Compile with warnings turned on", "yes" if os.name != "nt" else "no")) if os.name != "nt" : vars.Add(BoolVariable("coverage", "Compile with coverage information", "no")) if os.name == "posix" : vars.Add(BoolVariable("valgrind", "Run tests with valgrind", "no")) if os.name == "mac" : vars.Add(BoolVariable("universal", "Create universal binaries", "no")) if os.name == "nt" : vars.Add(PathVariable("vcredist", "MSVC redistributable dir", "", PathVariable.PathAccept)) if os.name == "nt" : vars.Add(PackageVariable("bonjour", "Bonjour SDK location", "yes")) vars.Add(PackageVariable("openssl", "OpenSSL location", "yes")) vars.Add(PathVariable("qt", "Qt location", "", PathVariable.PathAccept)) ################################################################################ # Set up default build & configure environment ################################################################################ env = Environment(CPPPATH = "#", ENV = {'PATH' : os.environ['PATH']}, variables = vars) Help(vars.GenerateHelpText(env)) env.Alias("dist", ["."]) # Default custom tools env.Tool("Test", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("WriteVal", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("BuildVersion", toolpath = ["#/BuildTools/SCons/Tools"]) if env["PLATFORM"] == "darwin" : env.Tool("Nib", toolpath = ["#/BuildTools/SCons/Tools"]) env.Tool("AppBundle", toolpath = ["#/BuildTools/SCons/Tools"]) if env["PLATFORM"] == "win32" : env.Tool("WindowsBundle", toolpath = ["#/BuildTools/SCons/Tools"]) # Override SConscript to handle tests oldSConscript = SConscript def SConscript(*arguments, **keywords) : if not keywords.get("test_only", False) or env["TEST"] : return apply(oldSConscript, arguments, keywords) # Default compiler flags env["CCFLAGS"] = env.get("ccflags", []) env["LINKFLAGS"] = env.get("linkflags", []) if env["optimize"] : env.Append(CCFLAGS = "-O2") if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["GL"]) env.Append(LINKFLAGS = ["/INCREMENTAL:NO", "/LTCG"]) if env["debug"] : if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/Zi", "/MDd"]) env.Append(LINKFLAGS = ["/DEBUG"]) else : env.Append(CCFLAGS = "-g") elif env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/MD"]) if env.get("universal", 0) : assert(env["PLATFORM"] == "darwin") env.Append(CCFLAGS = [ "-isysroot", "/Developer/SDKs/MacOSX10.4u.sdk", "-arch", "i386", "-arch", "ppc"]) env.Append(LINKFLAGS = [ "-mmacosx-version-min=10.4", "-Wl", "-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk", "-arch", "i386", "-arch", "ppc"]) if env["warnings"] : if env["PLATFORM"] == "win32" : env.Append(CCFLAGS = ["/Wall"]) else : env.Append(CCFLAGS = ["-W", "-Wall"]) #env.Append(CCFLAGS = ["-W", "-Wall", "-Wredundant-decls", "-pedantic", "-Wno-long-long", "-Woverloaded-virtual", "-Wundef", "-Wfloat-equal", "-Wold-style-cast"]) if env.get("coverage", 0) : assert(env["PLATFORM"] != "win32") env.Append(CCFLAGS = ["-fprofile-arcs", "-ftest-coverage"]) env.Append(LINKFLAGS = ["-fprofile-arcs", "-ftest-coverage"]) if env["PLATFORM"] == "win32" : env.Append(LIBS = ["user32", "dnsapi", "ws2_32", "wsock32"]) env.Append(CCFLAGS = ["/EHsc", "/nologo"]) env["LINKCOM"] = [env["LINKCOM"], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1'] env["SHLINKCOM"] = [env["SHLINKCOM"], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2'] if env["PLATFORM"] == "darwin" : env.Append(FRAMEWORKS = ["IOKit", "AppKit"]) # Testing env["TEST_TYPE"] = env["test"] env.Alias("check", ".") if "check" in ARGUMENTS or "check" in COMMAND_LINE_TARGETS : env["TEST_TYPE"] = "unit" env["TEST"] = (env["TEST_TYPE"] != "none") or env.GetOption("clean") if env.get("valgrind", 0) : env["TEST_RUNNER"] = "valgrind --suppressions=QA/valgrind.supp -q --leak-check=full --track-origins=yes " # Packaging if ARGUMENTS.get("SWIFT_INSTALLDIR", "") : env["SWIFT_INSTALLDIR"] = Dir(ARGUMENTS["SWIFT_INSTALLDIR"]).abspath conf_env = env.Clone() Export("env") Export("conf_env") ################################################################################ # Extend the default build environment (not affecting the configure env) # # Keeping both environments separated mostly because of SCons Issue 2391, # although it doesn't hurt to separate them (e.g. not have pretty printed # strings in config.log) ################################################################################ #if env["PLATFORM"] == "win32" : # env["MSVC_BATCH"] = 1 # Pretty output def colorize(command, target, color) : colors = { "red": "31", "green": "32", "yellow": "33", "blue": "34" } prefix = "" suffix = "" if sys.stdout.isatty() and env["PLATFORM"] != "win32": prefix = "\033[0;" + colors[color] + ";140m" suffix = "\033[0m" return " " + prefix + command + suffix + " " + target if int(ARGUMENTS.get("V", 0)) == 0: env["CCCOMSTR"] = colorize("CC", "$TARGET", "green") env["CXXCOMSTR"] = colorize("CXX", "$TARGET", "green") env["LINKCOMSTR"] = colorize("LINK", "$TARGET", "red") env["ARCOMSTR"] = colorize("AR", "$TARGET", "red") env["RANLIBCOMSTR"] = colorize("RANLIB", "$TARGET", "red") env["QT4_RCCCOMSTR"] = colorize("RCC", "$TARGET", "blue") env["QT4_UICCOMSTR"] = colorize("UIC", "$TARGET", "blue") env["QT4_MOCFROMHCOMSTR"] = colorize("MOC", "$TARGET", "blue") env["QT4_MOCFROMCXXCOMSTR"] = colorize("MOC", "$TARGET", "blue") env["GENCOMSTR"] = colorize("GEN", "$TARGET", "blue") env["RCCOMSTR"] = colorize("RC", "$TARGET", "blue") env["BUNDLECOMSTR"] = colorize("BUNDLE", "$TARGET", "blue") env["NIBCOMSTR"] = colorize("NIB", "$TARGET", "blue") env["NSISCOMSTR"] = colorize("NSIS", "$TARGET", "blue") env["INSTALLSTR"] = colorize("INSTALL", "$TARGET", "blue") env["TESTCOMSTR"] = colorize("TEST", "$SOURCE", "yellow") #Progress(colorize("DEP", "$TARGET", "red") def checkObjCHeader(context, header) : context.Message("Checking for Objective-C header " + header + " ... ") ret = context.TryCompile("#include \n#include <" + header + ">", ".m") context.Result(ret) return ret ################################################################################ # Platform configuration ################################################################################ if ARGUMENTS.get("force-configure", 0) : SCons.SConf.SetCacheMode("force") conf = Configure(conf_env) conf.CheckCXX() conf.CheckCC() if conf.CheckLib("z") : env.Append(LIBS = "z") env["ZLIB_FLAGS"] = "" else : SConscript("3rdParty/ZLib/SConscript") if conf.CheckLib("dl") : env.Append(LIBS = ["dl"]) if conf.CheckLib("c") : env.Append(LIBS = ["c"]) if conf.CheckLib("resolv") : env.Append(LIBS = ["resolv"]) # Expat if conf.CheckCHeader("expat.h") and conf.CheckLib("expat") : env["HAVE_EXPAT"] = 1 env["EXPAT_FLAGS"] = { "LIBS": ["expat"] } conf.Finish() # Xss env["HAVE_XSS"] = 0 if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" : xss_flags = { "LIBPATH": ["/usr/X11R6/lib"], "LIBS": ["X11", "Xss"] } xss_env = conf_env.Clone() xss_env.MergeFlags(xss_flags) conf = Configure(xss_env) if conf.CheckFunc("XScreenSaverQueryExtension") : env["HAVE_XSS"] = 1 env["XSS_FLAGS"] = xss_flags conf.Finish() # Sparkle env["HAVE_SPARKLE"] = 0 if env["PLATFORM"] == "darwin" : sparkle_flags = { "FRAMEWORKPATH": ["/Library/Frameworks"], "FRAMEWORKS": ["Sparkle"] } sparkle_env = conf_env.Clone() sparkle_env.MergeFlags(sparkle_flags) conf = Configure(sparkle_env, custom_tests = { "CheckObjCHeader" : checkObjCHeader }) if conf.CheckObjCHeader("Sparkle/Sparkle.h") : env["HAVE_SPARKLE"] = 1 env["SPARKLE_FLAGS"] = sparkle_flags env["SPARKLE_FRAMEWORK"] = "/Library/Frameworks/Sparkle.framework" conf.Finish() # LibXML conf = Configure(conf_env) if conf.CheckCHeader("libxml/parser.h") and conf.CheckLib("xml2") : env["HAVE_LIBXML"] = 1 env["LIBXML_FLAGS"] = { "LIBS": ["xml2"] } conf.Finish() if not env.get("HAVE_LIBXML", 0) : libxml_env = conf_env.Clone() libxml_env.Append(CPPPATH = ["/usr/include/libxml2"]) conf = Configure(libxml_env) if conf.CheckCHeader("libxml/parser.h") and conf.CheckLib("xml2") : env["HAVE_LIBXML"] = 1 env["LIBXML_FLAGS"] = { "CPPPATH": ["/usr/include/libxml2"], "LIBS": ["xml2"] } conf.Finish() # Bundled expat bundledExpat = False if not env.get("HAVE_EXPAT", 0) : print "Expat or LibXML not found. Using bundled Expat" SConscript("3rdParty/Expat/SConscript") env["HAVE_EXPAT"] = 1 bundledExpat = True # Qt if env["qt"] : env["QTDIR"] = env["qt"] # OpenSSL openssl_env = conf_env.Clone() use_openssl = bool(env["openssl"]) openssl_prefix = env["openssl"] if isinstance(env["openssl"], str) else "" openssl_flags = {} if openssl_prefix : openssl_flags = { "CPPPATH": [os.path.join(openssl_prefix, "include")] } if env["PLATFORM"] == "win32" : openssl_flags["LIBPATH"] = [os.path.join(openssl_prefix, "lib", "VC")] env["OPENSSL_DIR"] = openssl_prefix else : openssl_flags["LIBPATH"] = [os.path.join(openssl_prefix, "lib")] openssl_env.MergeFlags(openssl_flags) openssl_conf = Configure(openssl_env) if use_openssl and openssl_conf.CheckCHeader("openssl/ssl.h") : env["HAVE_OPENSSL"] = 1 env["OPENSSL_FLAGS"] = openssl_flags if env["PLATFORM"] == "win32" : env["OPENSSL_FLAGS"]["LIBS"] = ["libeay32MT", "ssleay32MT"] else: env["OPENSSL_FLAGS"]["LIBS"] = ["ssl", "crypto"] else : env["OPENSSL_FLAGS"] = "" openssl_conf.Finish() # Bonjour if env["PLATFORM"] == "darwin" : env["HAVE_BONJOUR"] = 1 elif env.get("bonjour", False) : bonjour_env = conf_env.Clone() bonjour_conf = Configure(bonjour_env) bonjour_flags = {} if env.get("bonjour") != True : bonjour_prefix = env["bonjour"] bonjour_flags["CPPPATH"] = [os.path.join(bonjour_prefix, "include")] bonjour_flags["LIBPATH"] = [os.path.join(bonjour_prefix, "lib", "win32")] bonjour_env.MergeFlags(bonjour_flags) if bonjour_conf.CheckCHeader("dns_sd.h") and bonjour_conf.CheckLib("dnssd") : env["HAVE_BONJOUR"] = 1 env["BONJOUR_FLAGS"] = bonjour_flags env["BONJOUR_FLAGS"]["LIBS"] = ["dnssd"] bonjour_conf.Finish() ################################################################################ # Project files # FIXME: We need to explicitly list the order of libraries here, because of # the exported FLAGS. We should put FLAGS in separate SConscript files, and # read these in before anything else, such that we don't need to manually # list modules in order. ################################################################################ # Third-party modules SConscript(dirs = [ "3rdParty/CppUnit", "3rdParty/Boost", "3rdParty/LibIDN", "3rdParty/CAres", "3rdParty/SQLite"]) # Checker SConscript(dirs = ["QA/Checker"], test_only = True) # Libraries SConscript(dirs = [ "Swiften", "SwifTools" ]) # Projects for dir in os.listdir(".") : if dir in ["QA", "Swiften", "SwifTools"] : continue sconscript = os.path.join(dir, "SConscript") if os.path.isfile(sconscript) : SConscript(sconscript) # Unit test runner SConscript(dirs = ["QA/UnitTest"], test_only = True) ################################################################################ # Print summary ################################################################################ print print " Build Configuration" print " -------------------" parsers = [] if env.get("HAVE_LIBXML", 0): parsers.append("LibXML") if env.get("HAVE_EXPAT", 0): parsers.append("Expat") if bundledExpat: parsers.append("(Bundled)") print " XML Parsers: " + ' '.join(parsers) print " TLS Support: " + ("OpenSSL" if env.get("HAVE_OPENSSL",0) else "Disabled") print " DNSSD Support: " + ("Bonjour" if env.get("HAVE_BONJOUR") else ("Avahi" if env.get("HAVE_AVAHI") else "Disabled")) print