diff options
| author | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) | 
| commit | f53a1ef582494458301b97bf6e546be52d7ff7e8 (patch) | |
| tree | 7571b5cbcbd8a8f1dd1c966c9045b6cb69f0e295 /BuildTools | |
| parent | 638345680d72ca6acaf123f2c8c1c391f696e371 (diff) | |
| download | swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.zip swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.tar.bz2  | |
Moving submodule contents back.
Diffstat (limited to 'BuildTools')
24 files changed, 1543 insertions, 0 deletions
diff --git a/BuildTools/.gitignore b/BuildTools/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/BuildTools/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/BuildTools/CheckTabs.py b/BuildTools/CheckTabs.py new file mode 100755 index 0000000..2cc1cf7 --- /dev/null +++ b/BuildTools/CheckTabs.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +import os, sys + +foundExpandedTabs = False + +for (path, dirs, files) in os.walk(".") : +	if not "3rdParty" in path and not ".sconf" in path : +		for filename in [os.path.join(path, file) for file in files if (file.endswith(".cpp") or file.endswith(".h")) and not "ui_" in file and not "moc_" in file and not "qrc_" in file] : +			file = open(filename, "r") +			contents = [] +			contentsChanged = False +			for line in file.readlines() : +				newline = "" +				previousChar = None +				pastInitialSpace = False +				for char in line : +					if not pastInitialSpace : +						if char == ' ' and previousChar == ' ' : +							contentsChanged = True +							previousChar = '\t' +							continue +						pastInitialSpace = (char != ' ') +					if previousChar : +						newline += previousChar +					previousChar = char +				if previousChar : +					newline += previousChar +				contents.append(newline) +			file.close() +			if contentsChanged : +				if len(sys.argv) > 1 and sys.argv[1] == "--fix" : +					print "Fixing tabs in " + filename +					file = open(filename, "w") +					file.write(''.join(contents)) +					file.close() +				else : +					foundExpandedTabs = True +					print filename + " contains expanded tabs" + +sys.exit(foundExpandedTabs) diff --git a/BuildTools/Copyrighter.py b/BuildTools/Copyrighter.py new file mode 100755 index 0000000..189dcf5 --- /dev/null +++ b/BuildTools/Copyrighter.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +#coding=utf-8 + +import os, re, datetime + +TEMPLATE = """/* + * Copyright (c) %(year)s  %(author)s. + * See the included COPYING file for license details. + */ + +""" + +def updateCopyright(fileName) : +  file = open(fileName) +  fileData = "" + +  author = "" +  startYear = "" +  endYear = "" +  previousCopyright = "" +   +  # Retrieve previous copyright information +  header = "" +  inHeader = False +  inSpaceBelowHeader = False +  lines = file.readlines() +  lines2 = lines +  for line in lines2 : +    lines.pop(0) +    if inSpaceBelowHeader : +      if line.strip() != "" : +        break +    elif inHeader : +      if line.startswith(" */") : +        inSpaceBelowHeader = True +      else : +        header += line +    else : +      if line.strip() == "" : +        continue +      elif line.startswith("/*") : +        inHeader = True +        header += line +      else : +        fileData += line +        break +  if "Copyright" in header : +    previousCopyright = header +    m = re.match("\* Copyright \(c\) (?P<startYear>\d\d\d\d)(-(?P<endYear>\d\d\d\d))? (?P<author>.*)", header) +    if m : +      author = m.group("author") +      startYear = m.group("startYear") +      endYear = m.group("endYear") +  elif header != "" : +    fileData = header +  file.close() + +  # Read in the rest of the data +  fileData += "".join(lines) + +  # Guess empty values +  if author == "" : +    if "Swift/" in fileName : +      author = "Kevin Smith" +    else : +      author = u"Remko Tronçon" +  if startYear == "" : +    startYear = datetime.date.today().strftime("%Y") +  elif endYear == "" : +    ## TODO: Guess end year by looking at git log --pretty=format:%ai -- <filename> +    pass + +  # Generate a copyright +  year = startYear + "-" + endYear if len(endYear) > 0 else startYear +  copyright = TEMPLATE % { +      "author" : author, +      "year" : year +    } + +  # Write the copyright to the file +  if copyright.encode("utf-8") != previousCopyright : +    file = open(fileName, "w") +    file.write(copyright.encode("utf-8")) +    file.write(fileData) +    file.close() + +for (path, dirs, files) in os.walk("Swiften/JID") : +  if "3rdParty" in path : +    continue +  for filename in files : +    if not filename.endswith(".cpp") and not filename.endswith(".h") : +      continue +    if filename.startswith("moc_") : +      continue +    fullFilename = path + "/" + filename +    updateCopyright(fullFilename) diff --git a/BuildTools/Coverage/.gitignore b/BuildTools/Coverage/.gitignore new file mode 100644 index 0000000..1a06816 --- /dev/null +++ b/BuildTools/Coverage/.gitignore @@ -0,0 +1 @@ +results diff --git a/BuildTools/Coverage/FilterLCovData.py b/BuildTools/Coverage/FilterLCovData.py new file mode 100755 index 0000000..a3a7ee5 --- /dev/null +++ b/BuildTools/Coverage/FilterLCovData.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# TODO: Add uncovered non-ignored files + +import sys, re, os.path + +assert(len(sys.argv) == 2) + +def isIgnored(file) : +  return (file.find("/Swiften/") == -1 and file.find("/Slimber/") == -1 and file.find("/Swift/") == -1) or (file.find("/UnitTest/") != -1 or file.find("/QA/") != -1) +   + +output = [] +inputFile = open(sys.argv[1]) +inIgnoredFile = False +for line in inputFile.readlines() : +  if inIgnoredFile : +    if line == "end_of_record\n" : +      inIgnoredFile = False +  else : +    if line.startswith("SF:") and isIgnored(line) : +      inIgnoredFile = True +    else : +      m = re.match("SF:(.*)", line) +      if m : +        line = "SF:" + os.path.realpath(m.group(1)) + "\n" +      output.append(line) +inputFile.close() + +outputFile = open(sys.argv[1], 'w') +outputFile.write(''.join(output)) +outputFile.close() diff --git a/BuildTools/Coverage/GenerateCoverageResults.sh b/BuildTools/Coverage/GenerateCoverageResults.sh new file mode 100755 index 0000000..f06c484 --- /dev/null +++ b/BuildTools/Coverage/GenerateCoverageResults.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# This script assumes that it is run from the toplevel directory + +SOURCE_DIR=. +SCRIPT_DIR=BuildTools/Coverage +LCOVDIR=3rdParty/LCov + +RESULTS_DIR=BuildTools/Coverage/results +OUTPUT_DIR=$RESULTS_DIR/coverage-`git log --pretty=format:%ct-%h | head -n 1` + +if [ ! -d $OUTPUT_DIR ]; then +	mkdir -p $OUTPUT_DIR +fi + +# Reset counters +$LCOVDIR/lcov --zerocounters --directory $SOURCE_DIR + +# Build & run all tests +scons coverage=1 test=all + +# Run SCons +$LCOVDIR/lcov --capture --directory $SOURCE_DIR -b $SOURCE_DIR --output-file $OUTPUT_DIR/all.info --test-name all +cp $OUTPUT_DIR/all.info $OUTPUT_DIR/all.info.orig +$SCRIPT_DIR/FilterLCovData.py $OUTPUT_DIR/all.info + +# Generate HTML +$LCOVDIR/gendesc -o $OUTPUT_DIR/descriptions $SCRIPT_DIR/descriptions.txt +$LCOVDIR/genhtml --no-function-coverage --title "Swift Coverage" --output-directory $OUTPUT_DIR $OUTPUT_DIR/all.info + +# Generate summary +$SCRIPT_DIR/GenerateSummary.py $OUTPUT_DIR/all.info $OUTPUT_DIR/summary diff --git a/BuildTools/Coverage/GenerateOverview.py b/BuildTools/Coverage/GenerateOverview.py new file mode 100755 index 0000000..8928afd --- /dev/null +++ b/BuildTools/Coverage/GenerateOverview.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +import sys, os.path + +assert(len(sys.argv) == 4) + +resultsDir = sys.argv[1] +summaryFile = sys.argv[2] +overviewFile = sys.argv[3] + +results = [] +for dir in os.listdir(resultsDir) : +  summary = os.path.join(resultsDir, dir, summaryFile) +  if os.path.exists(summary) : +    file = open(summary) +    lines = file.readlines() +    if len(lines) == 0 or len(lines[0].split("/")) != 2 : +      continue +    coveredCount = int(lines[0].split("/")[0]) +    totalCount = int(lines[0].split("/")[1]) +    results.append((dir,coveredCount,totalCount)) + +# Compute coverage chart URL +chartparams = ["chs=320x240", "cht=lc", "chtt=Coverage (Relative)", "chxt=y", "chxl=0:|50%|80%|100%|", "chxp=0,50,80,100"] +chartdata = [] +for (url,covered,total) in results : +  chartdata.append(str(100*covered/total)) +chartparams.append("chd=t:" + ",".join(chartdata)) +coverageChartURL = "http://chart.apis.google.com/chart?" + '&'.join(chartparams) + +# Compute the maximum of lines over time +maximumNumberOfLines = 0 +for (url,covered,total) in results : +  maximumNumberOfLines = max(maximumNumberOfLines,total) + +# Compute code chart URL +chartparams = ["chs=320x240", "cht=lc", "chtt=Coverage (Absolute)", "chxt=y", "chxl=0:|" + str(maximumNumberOfLines) + "|", "chxp=0,100", "chm=b,FF0000,0,1,0|b,80C65A,1,2,0", "chco=00000000,00000000,00000000"] +coveredLinesData = [] +totalLinesData = [] +nullLinesData = [] +for (url,covered,total) in results : +  coveredLinesData.append(str(100*covered/maximumNumberOfLines)) +  totalLinesData.append(str(100*total/maximumNumberOfLines)) +  nullLinesData.append("0") +chartparams.append("chd=t:" + ",".join(totalLinesData) + "|" + ",".join(coveredLinesData) + "|" + ",".join(nullLinesData)) +codeChartURL = "http://chart.apis.google.com/chart?" + '&'.join(chartparams) + + +# Output page +output = open(os.path.join(resultsDir,overviewFile), 'w') +output.write("<img src=\"%(url)s\"s/>" % {'url' : coverageChartURL}) +output.write("<img src=\"%(url)s\"s/>" % {'url' : codeChartURL}) +output.write("<ul>\n") +for (url,covered,total) in results : +  output.write("<li><a href='%(url)s/index.html'>%(url)s</a> %(percentage)s%% (%(covered)s/%(total)s)</li>\n" % { +      'url' : url,  +      'percentage' : 100*covered / total,  +      'covered' : covered,  +      'total' : total  +    }) +output.write("</ul>") +output.close() + diff --git a/BuildTools/Coverage/GenerateSummary.py b/BuildTools/Coverage/GenerateSummary.py new file mode 100755 index 0000000..ec94a4f --- /dev/null +++ b/BuildTools/Coverage/GenerateSummary.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import sys, re + +assert(len(sys.argv) == 3) + +inputFile = open(sys.argv[1]) +currentFile = "" +coverage = {} +for line in inputFile.readlines() : +  line = line.strip() +  m = re.match("^SF:(.*)", line) +  if m : +    currentFile = m.group(1) +  else : +    m = re.match("^DA:(\d+),(\d+)", line) +    if m : +      currentFileCoverage = coverage.get(currentFile, {}) +      line = int(m.group(1)) +      count = int(m.group(2)) +      currentFileCoverage[line] = currentFileCoverage.get(line, 0) + count +      coverage[currentFile] = currentFileCoverage +inputFile.close() + +totalLines = 0 +coveredLines = 0 +for c in coverage.values() : +  totalLines += len(c) +  for l in c.values() : +    if l > 0 : +      coveredLines += 1 + +outputFile = open(sys.argv[2], 'w') +outputFile.write(str(coveredLines) + "/" + str(totalLines)) +outputFile.close() diff --git a/BuildTools/Coverage/descriptions.txt b/BuildTools/Coverage/descriptions.txt new file mode 100644 index 0000000..5b07e04 --- /dev/null +++ b/BuildTools/Coverage/descriptions.txt @@ -0,0 +1,2 @@ +all +  All tests  diff --git a/BuildTools/Git/Hooks/pre-commit b/BuildTools/Git/Hooks/pre-commit new file mode 100755 index 0000000..9ffc1c7 --- /dev/null +++ b/BuildTools/Git/Hooks/pre-commit @@ -0,0 +1,7 @@ +#!/bin/sh + +echo "Checking tabs ..." +if ! BuildTools/CheckTabs.py; then +	echo "Expanded tabs found. Aborting commit." +	exit -1 +fi diff --git a/BuildTools/MSVS/.gitignore b/BuildTools/MSVS/.gitignore new file mode 100644 index 0000000..95a4834 --- /dev/null +++ b/BuildTools/MSVS/.gitignore @@ -0,0 +1,4 @@ +*.suo +*.ncp +Slimber +Swift diff --git a/BuildTools/MSVS/GenerateProjects.py b/BuildTools/MSVS/GenerateProjects.py new file mode 100644 index 0000000..d13df08 --- /dev/null +++ b/BuildTools/MSVS/GenerateProjects.py @@ -0,0 +1,100 @@ +import os, os.path + +projects = [("Swift", "Swift\QtUI\Swift.exe"), ("Slimber", "Slimber\Qt\Slimber.exe")] + +for (project, outputbin) in projects : +	if not os.path.exists(project) : +		os.mkdir(project) +	output = open(os.path.join(project, project + ".vcproj"), "w") + +	headers = [] +	sources = [] +	for root, dirs, files in os.walk(os.path.join("..", "..", project)) : +		for file in files : +			if file.endswith(".h") : +				headers.append('<File RelativePath="' + os.path.join("..", root, file) + '" />') +			elif file.endswith(".cpp") :	 +				sources.append('<File RelativePath="' + os.path.join("..", root, file) + '" />') + +	output.write("""<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject +	ProjectType="Visual C++" +	Version="9.00" +	Name="%(project)s" +	Keyword="MakeFileProj" +	TargetFrameworkVersion="196613" +	> +	<Platforms> +		<Platform +			Name="Win32" +		/> +	</Platforms> +	<ToolFiles> +	</ToolFiles> +	<Configurations> +		<Configuration +			Name="Debug|Win32" +			OutputDirectory="$(ConfigurationName)" +			IntermediateDirectory="$(ConfigurationName)" +			ConfigurationType="0" +			> +			<Tool +				Name="VCNMakeTool" +				BuildCommandLine="cd ..\..\..\ && scons debug=1 %(project)s" +				ReBuildCommandLine="" +				CleanCommandLine="cd ..\..\..\ && scons -c debug=1 %(project)s" +				Output="..\..\..\%(output)s" +				PreprocessorDefinitions="WIN32;_DEBUG" +				IncludeSearchPath="" +				ForcedIncludes="" +				AssemblySearchPath="" +				ForcedUsingAssemblies="" +				CompileAsManaged="" +			/> +		</Configuration> +		<Configuration +			Name="Release|Win32" +			OutputDirectory="$(ConfigurationName)" +			IntermediateDirectory="$(ConfigurationName)" +			ConfigurationType="0" +			> +			<Tool +				Name="VCNMakeTool" +				BuildCommandLine="cd ..\..\..\ && scons %(project)s" +				ReBuildCommandLine="" +				CleanCommandLine="cd ..\..\..\ && scons -c %(project)s" +				Output="..\..\..\%(output)s" +				PreprocessorDefinitions="WIN32;NDEBUG" +				IncludeSearchPath="" +				ForcedIncludes="" +				AssemblySearchPath="" +				ForcedUsingAssemblies="" +				CompileAsManaged="" +			/> +		</Configuration> +	</Configurations> +	<References> +	</References> +	<Files> +		<Filter +			Name="Source Files" +			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" +			> +			%(sources)s +		</Filter> +		<Filter +			Name="Header Files" +			Filter="h;hpp;hxx;hm;inl;inc;xsd" +			> +			%(headers)s +		</Filter> +		<Filter +			Name="Resource Files" +			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" +			> +		</Filter> +	</Files> +	<Globals> +	</Globals> +</VisualStudioProject>""" % { "project": project, "output" : outputbin, "headers" : '\n'.join(headers), "sources": '\n'.join(sources) }) +	output.close() diff --git a/BuildTools/MSVS/Swift.sln b/BuildTools/MSVS/Swift.sln new file mode 100644 index 0000000..2724f81 --- /dev/null +++ b/BuildTools/MSVS/Swift.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Swift", "Swift\Swift.vcproj", "{C67C3A5B-1382-4B4A-88F7-3BFC98DA43A2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Slimber", "Slimber\Slimber.vcproj", "{597242B2-A667-47A1-B69E-D2C4281183D0}" +EndProject +Global +	GlobalSection(SolutionConfigurationPlatforms) = preSolution +		Debug|Win32 = Debug|Win32 +		Release|Win32 = Release|Win32 +	EndGlobalSection +	GlobalSection(ProjectConfigurationPlatforms) = postSolution +		{C67C3A5B-1382-4B4A-88F7-3BFC98DA43A2}.Debug|Win32.ActiveCfg = Debug|Win32 +		{C67C3A5B-1382-4B4A-88F7-3BFC98DA43A2}.Debug|Win32.Build.0 = Debug|Win32 +		{C67C3A5B-1382-4B4A-88F7-3BFC98DA43A2}.Release|Win32.ActiveCfg = Release|Win32 +		{C67C3A5B-1382-4B4A-88F7-3BFC98DA43A2}.Release|Win32.Build.0 = Release|Win32 +		{597242B2-A667-47A1-B69E-D2C4281183D0}.Debug|Win32.ActiveCfg = Debug|Win32 +		{597242B2-A667-47A1-B69E-D2C4281183D0}.Debug|Win32.Build.0 = Debug|Win32 +		{597242B2-A667-47A1-B69E-D2C4281183D0}.Release|Win32.ActiveCfg = Release|Win32 +		{597242B2-A667-47A1-B69E-D2C4281183D0}.Release|Win32.Build.0 = Release|Win32 +	EndGlobalSection +	GlobalSection(SolutionProperties) = preSolution +		HideSolutionNode = FALSE +	EndGlobalSection +EndGlobal diff --git a/BuildTools/SCons/SConstruct b/BuildTools/SCons/SConstruct new file mode 100644 index 0000000..98202a5 --- /dev/null +++ b/BuildTools/SCons/SConstruct @@ -0,0 +1,399 @@ +import sys, os +sys.path.append(Dir("BuildTools/SCons").abspath) +import SCons.SConf + +################################################################################ +# Build variables +################################################################################ + +vars = Variables(os.path.join(Dir("#").abspath, "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")) +vars.Add(BoolVariable("max_jobs", "Build with maximum number of parallel jobs", "no")) +vars.Add(EnumVariable("target", "Choose a target platform for compilation", "native", ["native", "iphone-simulator", "iphone-device"])) +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" or (os.name == "posix" and os.uname()[0] == "Darwin"): +	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) +   +# Max out the number of jobs +if env["max_jobs"] : +	try : +		import multiprocessing +		SetOption("num_jobs", multiprocessing.cpu_count()) +	except NotImplementedError : +		pass + +# 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 + +# cross-compiling +target = env["target"] +if target in ("iphone-device", "iphone-simulator"): +   if target == "iphone-device": +      sdkPart = "iPhoneOS" +      env["CC"] = "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-gcc-4.0.1" +      env["CXX"] = "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1" +      env["PATH"] = "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/" +      env["LD"] = env["CC"] +#      env["openssl"] = "#/3rdParty/openssl-0.9.8l-arm" +      targetIncludesArch = "arm" + +   if target == "iphone-simulator": +      sdkPart = "iPhoneSimulator" +      env.Append(CCFLAGS = ["-arch", "i386"]) +      env.Append(LINKFLAGS = ["-arch", "i386"]) +      targetIncludesArch = "i686" + +   sdkVer = "3.0" +   sdk = "/Developer/Platforms/" + sdkPart + ".platform/Developer/SDKs/" + sdkPart + sdkVer + ".sdk" + +   env["FRAMEWORKS"] = ["CoreFoundation", "Foundation", "UIKit", "CoreGraphics"] +   env.Append(LINKFLAGS = ["-L\"" + sdk + "/usr/lib\"", "-F\"" + sdk + "/System/Library/Frameworks\"", "-F\"" + sdk + "/System/Library/PrivateFrameworks\""]) +   env["CPPPATH"] = ["/Users/kismith/devel/swift/iPhone/Swiftly/swift/", "/Developer/Platforms/" + sdkPart + ".platform/Developer/usr/lib/gcc/" + targetIncludesArch + "-apple-darwin9/4.0.1/include/", sdk + "/usr/include", sdk + "/usr/include/c++/4.0.0/" + targetIncludesArch + "-apple-darwin9", sdk + "/usr/include/c++/4.0.0", "/Developer/Platforms/" + sdkPart + ".platform/Developer/usr/include/"] + +# end cross compiling stuff + + +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 <Cocoa/Cocoa.h>\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) + +if not conf.CheckCXX() or not conf.CheckCC() : +	print "Error: You need a working compiler" +	Exit(1) + +env["HAVE_ZLIB"] = True +if conf.CheckLib("z") : +	env.Append(LIBS = "z") +	env["ZLIB_FLAGS"] = "" +else : +	env["ZLIB_BUNDLED"] = True + +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 +	env["EXPAT_BUNDLED"] = 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. +################################################################################ + +# Modules +modules = [] +for dir in os.listdir(Dir("#").abspath) : +	full_dir = os.path.join(Dir("#").abspath, dir) +	if not os.path.isdir(full_dir) : +		continue +	sconscript = os.path.join(full_dir, "SConscript") +	if os.path.isfile(sconscript) : +		modules.append(dir) +for dir in os.listdir(Dir("#/3rdParty").abspath) : +	full_dir = os.path.join(Dir("#/3rdParty").abspath, dir) +	if not os.path.isdir(full_dir) : +		continue +	sconscript = os.path.join(full_dir, "SConscript") +	if os.path.isfile(sconscript) : +		modules.append("3rdParty/" + dir) + +# Flags +for stage in ["flags", "build", "test"] : +	env["SCONS_STAGE"] = stage +	SConscript(dirs = map(lambda x : "#/" + x, modules)) + +################################################################################ +# 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 env.get("EXPAT_BUNDLED", False) : +		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 diff --git a/BuildTools/SCons/Tools/AppBundle.py b/BuildTools/SCons/Tools/AppBundle.py new file mode 100644 index 0000000..12667f0 --- /dev/null +++ b/BuildTools/SCons/Tools/AppBundle.py @@ -0,0 +1,52 @@ +import SCons.Util + +def generate(env) : +  def createAppBundle(env, bundle, version = "1.0", resources = [], frameworks = [], info = {}) : +    bundleDir = bundle + ".app" +    bundleContentsDir = bundleDir + "/Contents" +    resourcesDir = bundleContentsDir + "/Resources" +    frameworksDir = bundleContentsDir + "/Frameworks" +    env.Install(bundleContentsDir + "/MacOS", bundle) +    env.WriteVal(bundleContentsDir + "/PkgInfo", env.Value("APPL\77\77\77\77")) + +    infoDict = { +        "CFBundleDevelopmentRegion" : "English", +        "CFBundleExecutable" : bundle, +        "CFBundleIdentifier" : "im.swift." + bundle, +        "CFBundleInfoDictionaryVersion" : "6.0", +        "CFBundleName" : bundle, +        "CFBundlePackageType" : "APPL", +        "CFBundleSignature": "\77\77\77\77", +        "CFBundleVersion" : version, +        "CFBundleIconFile" : bundle, +        "NSPrincipalClass" : "NSApplication", +        "NSHumanReadableCopyright" : unichr(0xA9) + " 2009 Swift Development Team.\nAll Rights Reserved." +      } +    infoDict.update(info) +     +    plist = """<?xml version="1.0" encoding="UTF-8"?> +  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +  <plist version="1.0"> +  <dict> +  """ +    for key, value in infoDict.items() : +      plist += "<key>" + key + "</key>\n" +      plist += "<string>" + value.encode("utf-8") + "</string>\n" +    plist += """</dict> +  </plist> +  """ +    env.WriteVal(bundleContentsDir + "/Info.plist", env.Value(plist)) + +    for resource in resources : +      env.Install(resourcesDir, resource) + +    for framework in frameworks : +      env.Install(frameworksDir, framework) + +    return env.Dir(bundleDir) + +  env.AddMethod(createAppBundle, "AppBundle") + + +def exists(env) : +  return env["PLATFORM"] == "darwin" diff --git a/BuildTools/SCons/Tools/BuildVersion.py b/BuildTools/SCons/Tools/BuildVersion.py new file mode 100644 index 0000000..530ef8a --- /dev/null +++ b/BuildTools/SCons/Tools/BuildVersion.py @@ -0,0 +1,17 @@ +import SCons.Util + +import Version + +def generate(env) : +  def createBuildVersion(env, target, version = None) : +    buildVersion = """#pragma once + +static const char* buildVersion = \"%(buildVersion)s\";\n +""" % { "buildVersion" : Version.getBuildVersion(version) } +    env.WriteVal(target, env.Value(buildVersion)) + +  env.AddMethod(createBuildVersion, "BuildVersion") + + +def exists(env) : +  return true diff --git a/BuildTools/SCons/Tools/Nib.py b/BuildTools/SCons/Tools/Nib.py new file mode 100644 index 0000000..ccfd884 --- /dev/null +++ b/BuildTools/SCons/Tools/Nib.py @@ -0,0 +1,12 @@ +import SCons.Util + +def generate(env) : +  env["IBTOOL"] = "ibtool" +  env["BUILDERS"]["Nib"] = SCons.Builder.Builder( +      action = SCons.Action.Action("$IBTOOL --errors --warnings --notices --output-format human-readable-text --compile $TARGET $SOURCE", cmdstr = "$NIBCOMSTR"), +      suffix = ".nib", +      src_suffix = ".xib", +      single_source = True) + +def exists(env) : +  return env["PLATFORM"] == "darwin" diff --git a/BuildTools/SCons/Tools/Test.py b/BuildTools/SCons/Tools/Test.py new file mode 100644 index 0000000..aaed222 --- /dev/null +++ b/BuildTools/SCons/Tools/Test.py @@ -0,0 +1,13 @@ +import SCons.Util + +def generate(env) : +  def registerTest(env, target, type = "unit") : +    if env["TEST_TYPE"] == "all" or env["TEST_TYPE"] == type : +      cmd = target[0].abspath if SCons.Util.is_List(target) else target.abspath +      env.Command("**dummy**", target,  +          SCons.Action.Action(env.get("TEST_RUNNER", "") + cmd, cmdstr = "$TESTCOMSTR")) + +  env.AddMethod(registerTest, "Test") + +def exists(env) : +  return True diff --git a/BuildTools/SCons/Tools/WindowsBundle.py b/BuildTools/SCons/Tools/WindowsBundle.py new file mode 100644 index 0000000..bc690af --- /dev/null +++ b/BuildTools/SCons/Tools/WindowsBundle.py @@ -0,0 +1,17 @@ +import SCons.Util, os + +def generate(env) : +  def createWindowsBundle(env, bundle, resources = [], qtimageformats = [], qtlibs = []) : +    env.Install(bundle, bundle + ".exe") +    for lib in qtlibs : +      env.Install(bundle, os.path.join(env["QTDIR"], "bin", lib + ".dll")) +    env.Install(os.path.join(bundle, "imageformats"), [os.path.join(env["QTDIR"], "plugins", "imageformats", "q" + codec + "4.dll") for codec in qtimageformats]) + +    for resource in resources : +      env.Install(bundle, resource) + +  env.AddMethod(createWindowsBundle, "WindowsBundle") + +def exists(env) : +  return env["PLATFORM"] == "win32" + diff --git a/BuildTools/SCons/Tools/WriteVal.py b/BuildTools/SCons/Tools/WriteVal.py new file mode 100644 index 0000000..e39ad82 --- /dev/null +++ b/BuildTools/SCons/Tools/WriteVal.py @@ -0,0 +1,14 @@ +import SCons.Util + +def generate(env) : +  def writeVal(env, target, source) : +    f = open(str(target[0]), 'wb') +    f.write(source[0].get_contents()) +    f.close() + +  env["BUILDERS"]["WriteVal"] = SCons.Builder.Builder( +    action = SCons.Action.Action(writeVal, cmdstr = "$GENCOMSTR"), +    single_source = True) + +def exists(env) : +  return True diff --git a/BuildTools/SCons/Tools/nsis.py b/BuildTools/SCons/Tools/nsis.py new file mode 100644 index 0000000..567876d --- /dev/null +++ b/BuildTools/SCons/Tools/nsis.py @@ -0,0 +1,37 @@ +import re, os +import SCons.Util +nsisFiles_re = re.compile(r'^\s*File "([^"]*)"', re.M) + +""" +TODO: +	- Extract the target from the nsis file +	- When a target is provided use the output function +""" + +def generate(env) : +	"""Add Builders and construction variables for qt to an Environment.""" +	Builder = SCons.Builder.Builder + +	env['NSIS_MAKENSIS'] = 'makensis' +	env['NSIS_OPTIONS'] = ["/V2"] +	def winToLocalReformat(path) : +		return os.path.join(*path.split("\\")) +	def scanNsisContent(node, env, path, arg): +		contents = node.get_contents() +		includes = nsisFiles_re.findall(contents) +		includes = [ winToLocalReformat(include) for include in includes ] +		return filter(lambda x: x.rfind('*')==-1, includes) +	nsisscanner = env.Scanner(name = 'nsisfile', +		function = scanNsisContent, +		argument = None, +		skeys = ['.nsi']) +	nsisbuilder = Builder( +		action = SCons.Action.Action('$NSIS_MAKENSIS $NSIS_OPTIONS $SOURCE', cmdstr = '$NSISCOMSTR'), +		source_scanner = nsisscanner, +		single_source = True +		) +	env.Append( BUILDERS={'Nsis' : nsisbuilder} ) + +def exists(env) : +	return True + diff --git a/BuildTools/SCons/Tools/qt4.py b/BuildTools/SCons/Tools/qt4.py new file mode 100644 index 0000000..0a84c03 --- /dev/null +++ b/BuildTools/SCons/Tools/qt4.py @@ -0,0 +1,517 @@ + +"""SCons.Tool.qt + +Tool-specific initialization for Qt. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "/home/scons/scons/branch.0/branch.96/baseline/src/engine/SCons/Tool/qt.py 0.96.92.D001 2006/04/10 23:13:27 knight" + +import os.path +import re + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Scanner +import SCons.Tool +import SCons.Util + +class ToolQtWarning(SCons.Warnings.Warning): +	pass + +class GeneratedMocFileNotIncluded(ToolQtWarning): +	pass + +class QtdirNotFound(ToolQtWarning): +	pass + +SCons.Warnings.enableWarningClass(ToolQtWarning) + +qrcinclude_re = re.compile(r'<file>([^<]*)</file>', re.M) + +def transformToWinePath(path) : +	return os.popen('winepath -w "%s"'%path).read().strip().replace('\\','/') + +header_extensions = [".h", ".hxx", ".hpp", ".hh"] +if SCons.Util.case_sensitive_suffixes('.h', '.H'): +	header_extensions.append('.H') +# TODO: The following two lines will work when integrated back to SCons +# TODO: Meanwhile the third line will do the work +#cplusplus = __import__('c++', globals(), locals(), []) +#cxx_suffixes = cplusplus.CXXSuffixes +cxx_suffixes = [".c", ".cxx", ".cpp", ".cc"] + +def checkMocIncluded(target, source, env): +	moc = target[0] +	cpp = source[0] +	# looks like cpp.includes is cleared before the build stage :-( +	# not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ +	path = SCons.Defaults.CScan.path_function(env, moc.cwd) +	includes = SCons.Defaults.CScan(cpp, env, path) +	if not moc in includes: +		SCons.Warnings.warn( +			GeneratedMocFileNotIncluded, +			"Generated moc file '%s' is not included by '%s'" % +			(str(moc), str(cpp))) + +def find_file(filename, paths, node_factory): +	for dir in paths: +		node = node_factory(filename, dir) +		if node.rexists(): +			return node +	return None + +class _Automoc: +	""" +	Callable class, which works as an emitter for Programs, SharedLibraries and +	StaticLibraries. +	""" + +	def __init__(self, objBuilderName): +		self.objBuilderName = objBuilderName +		 +	def __call__(self, target, source, env): +		""" +		Smart autoscan function. Gets the list of objects for the Program +		or Lib. Adds objects and builders for the special qt files. +		""" +		try: +			if int(env.subst('$QT4_AUTOSCAN')) == 0: +				return target, source +		except ValueError: +			pass +		try: +			debug = int(env.subst('$QT4_DEBUG')) +		except ValueError: +			debug = 0 +		 +		# some shortcuts used in the scanner +		splitext = SCons.Util.splitext +		objBuilder = getattr(env, self.objBuilderName) + +		# some regular expressions: +		# Q_OBJECT detection +		q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')  +		# cxx and c comment 'eater' +		#comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') +		# CW: something must be wrong with the regexp. See also bug #998222 +		#	 CURRENTLY THERE IS NO TEST CASE FOR THAT +		 +		# The following is kind of hacky to get builders working properly (FIXME) +		objBuilderEnv = objBuilder.env +		objBuilder.env = env +		mocBuilderEnv = env.Moc4.env +		env.Moc4.env = env +		 +		# make a deep copy for the result; MocH objects will be appended +		out_sources = source[:] + +		for obj in source: +			if isinstance(obj,basestring):	# big kludge! +				print "scons: qt4: '%s' MAYBE USING AN OLD SCONS VERSION AND NOT CONVERTED TO 'File'. Discarded." % str(obj) +				continue +			if not obj.has_builder(): +				# binary obj file provided +				if debug: +					print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) +				continue +			cpp = obj.sources[0] +			if not splitext(str(cpp))[1] in cxx_suffixes: +				if debug: +					print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp)  +				# c or fortran source +				continue +			#cpp_contents = comment.sub('', cpp.get_contents()) +			try: +				cpp_contents = cpp.get_contents() +			except: continue # may be an still not generated source +			h=None +			for h_ext in header_extensions: +				# try to find the header file in the corresponding source +				# directory +				hname = splitext(cpp.name)[0] + h_ext +				h = find_file(hname, (cpp.get_dir(),), env.File) +				if h: +					if debug: +						print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) +					#h_contents = comment.sub('', h.get_contents()) +					h_contents = h.get_contents() +					break +			if not h and debug: +				print "scons: qt: no header for '%s'." % (str(cpp)) +			if h and q_object_search.search(h_contents): +				# h file with the Q_OBJECT macro found -> add moc_cpp +				moc_cpp = env.Moc4(h) +				moc_o = objBuilder(moc_cpp) +				out_sources.append(moc_o) +				#moc_cpp.target_scanner = SCons.Defaults.CScan +				if debug: +					print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) +			if cpp and q_object_search.search(cpp_contents): +				# cpp file with Q_OBJECT macro found -> add moc +				# (to be included in cpp) +				moc = env.Moc4(cpp) +				env.Ignore(moc, moc) +				if debug: +					print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) +				#moc.source_scanner = SCons.Defaults.CScan +		# restore the original env attributes (FIXME) +		objBuilder.env = objBuilderEnv +		env.Moc4.env = mocBuilderEnv + +		return (target, out_sources) + +AutomocShared = _Automoc('SharedObject') +AutomocStatic = _Automoc('StaticObject') + +def _detect(env): +	"""Not really safe, but fast method to detect the QT library""" +	try: return env['QTDIR'] +	except KeyError: pass + +	try: return os.environ['QTDIR'] +	except KeyError: pass + +	moc = env.WhereIs('moc-qt4') or env.WhereIs('moc4') or env.WhereIs('moc') +	if moc: +		import sys +		if sys.platform == "darwin" : +			return "" +		QTDIR = os.path.dirname(os.path.dirname(moc)) +		SCons.Warnings.warn( +			QtdirNotFound, +			"QTDIR variable is not defined, using moc executable as a hint (QTDIR=%s)" % QTDIR) +		return QTDIR + +	raise SCons.Errors.StopError( +		QtdirNotFound, +		"Could not detect Qt 4 installation") +	return None + +def generate(env): +	"""Add Builders and construction variables for qt to an Environment.""" + +	def locateQt4Command(env, command, qtdir) : +		if len(qtdir) == 0 : +			qtdir = "/usr" +		suffixes = [ +			'-qt4', +			'-qt4.exe', +			'4', +			'4.exe', +			'', +			'.exe', +		] +		triedPaths = [] +		for suffix in suffixes : +			fullpath = os.path.join(qtdir,'bin',command + suffix) +			if os.access(fullpath, os.X_OK) : +				return fullpath +			triedPaths.append(fullpath) + +		fullpath = env.Detect([command+'-qt4', command+'4', command]) +		if not (fullpath is None) : return fullpath + +		raise Exception("Qt4 command '" + command + "' not found. Tried: " + ', '.join(triedPaths)) +		 + +	CLVar = SCons.Util.CLVar +	Action = SCons.Action.Action +	Builder = SCons.Builder.Builder +	splitext = SCons.Util.splitext + +	env['QTDIR']	= _detect(env) +	# TODO: 'Replace' should be 'SetDefault' +#	env.SetDefault( +	env.Replace( +		QTDIR  = _detect(env), +		# TODO: This is not reliable to QTDIR value changes but needed in order to support '-qt4' variants +		QT4_MOC = locateQt4Command(env,'moc', env['QTDIR']), +		QT4_UIC = locateQt4Command(env,'uic', env['QTDIR']), +		QT4_RCC = locateQt4Command(env,'rcc', env['QTDIR']), +		QT4_LUPDATE = locateQt4Command(env,'lupdate', env['QTDIR']), +		QT4_LRELEASE = locateQt4Command(env,'lrelease', env['QTDIR']), +		QT4_LIB = '', # KLUDGE to avoid linking qt3 library + +		QT4_AUTOSCAN = 1, # Should the qt tool try to figure out, which sources are to be moc'ed? + +		# Some QT specific flags. I don't expect someone wants to +		# manipulate those ... +		QT4_UICFLAGS = CLVar(''), +		QT4_MOCFROMHFLAGS = CLVar(''), +		QT4_MOCFROMCXXFLAGS = CLVar('-i'), +		QT4_QRCFLAGS = '', + +		# suffixes/prefixes for the headers / sources to generate +		QT4_UISUFFIX = '.ui', +		QT4_UICDECLPREFIX = 'ui_', +		QT4_UICDECLSUFFIX = '.h', +		QT4_MOCHPREFIX = 'moc_', +		QT4_MOCHSUFFIX = '$CXXFILESUFFIX', +		QT4_MOCCXXPREFIX = '', +		QT4_MOCCXXSUFFIX = '.moc', +		QT4_QRCSUFFIX = '.qrc', +		QT4_QRCCXXSUFFIX = '$CXXFILESUFFIX', +		QT4_QRCCXXPREFIX = 'qrc_', +		QT4_MOCCPPPATH = [], +		QT4_MOCINCFLAGS = '$( ${_concat("-I", QT4_MOCCPPPATH, INCSUFFIX, __env__, RDirs)} $)', + +		# Commands for the qt support ... +		QT4_UICCOM = '$QT4_UIC $QT4_UICFLAGS -o $TARGET $SOURCE', +		QT4_MOCFROMHCOM = '$QT4_MOC $QT4_MOCFROMHFLAGS $QT4_MOCINCFLAGS -o $TARGET $SOURCE', +		QT4_MOCFROMCXXCOM = [ +			'$QT4_MOC $QT4_MOCFROMCXXFLAGS $QT4_MOCINCFLAGS -o $TARGET $SOURCE', +			Action(checkMocIncluded,None)], +		QT4_LUPDATECOM = '$QT4_LUPDATE $SOURCE -ts $TARGET', +		QT4_LRELEASECOM = '$QT4_LRELEASE $SOURCE', +		QT4_RCCCOM = '$QT4_RCC $QT4_QRCFLAGS -name $SOURCE $SOURCE -o $TARGET', +		) +	if len(env["QTDIR"]) > 0 : +		env.Replace(QT4_LIBPATH = os.path.join('$QTDIR', 'lib')) + +	# Translation builder +	tsbuilder = Builder( +		action = SCons.Action.Action('$QT4_LUPDATECOM'), #,'$QT4_LUPDATECOMSTR'), +		multi=1 +		) +	env.Append( BUILDERS = { 'Ts': tsbuilder } ) +	qmbuilder = Builder( +		action = SCons.Action.Action('$QT4_LRELEASECOM'),# , '$QT4_LRELEASECOMSTR'), +		src_suffix = '.ts', +		suffix = '.qm', +		single_source = True +		) +	env.Append( BUILDERS = { 'Qm': qmbuilder } ) + +	# Resource builder +	def scanResources(node, env, path, arg): +		# I've being careful on providing names relative to the qrc file +		# If that was not needed that code could be simplified a lot +		def recursiveFiles(basepath, path) : +			result = [] +			for item in os.listdir(os.path.join(basepath, path)) : +				itemPath = os.path.join(path, item) +				if os.path.isdir(os.path.join(basepath, itemPath)) : +					result += recursiveFiles(basepath, itemPath) +				else: +					result.append(itemPath) +			return result +		contents = node.get_contents() +		includes = qrcinclude_re.findall(contents) +		qrcpath = os.path.dirname(node.path) +		dirs = [included for included in includes if os.path.isdir(os.path.join(qrcpath,included))] +		# dirs need to include files recursively +		for dir in dirs : +			includes.remove(dir) +			includes+=recursiveFiles(qrcpath,dir) +		return includes +	qrcscanner = SCons.Scanner.Scanner(name = 'qrcfile', +		function = scanResources, +		argument = None, +		skeys = ['.qrc']) +	qrcbuilder = Builder( +		action = SCons.Action.Action('$QT4_RCCCOM', cmdstr = '$QT4_RCCCOMSTR'),  +		source_scanner = qrcscanner, +		src_suffix = '$QT4_QRCSUFFIX', +		suffix = '$QT4_QRCCXXSUFFIX', +		prefix = '$QT4_QRCCXXPREFIX', +		single_source = True +		) +	env.Append( BUILDERS = { 'Qrc': qrcbuilder } ) + +	# Interface builder +	uic4builder = Builder( +		action = SCons.Action.Action('$QT4_UICCOM', cmdstr = '$QT4_UICCOMSTR'),  +		src_suffix='$QT4_UISUFFIX', +		suffix='$QT4_UICDECLSUFFIX', +		prefix='$QT4_UICDECLPREFIX', +		single_source = True +		#TODO: Consider the uiscanner on new scons version +		) +	env['BUILDERS']['Uic4'] = uic4builder + +	# Metaobject builder +	mocBld = Builder(action={}, prefix={}, suffix={}) +	for h in header_extensions: +		act = SCons.Action.Action('$QT4_MOCFROMHCOM', cmdstr = '$QT4_MOCFROMHCOMSTR') +		mocBld.add_action(h, act) +		mocBld.prefix[h] = '$QT4_MOCHPREFIX' +		mocBld.suffix[h] = '$QT4_MOCHSUFFIX' +	for cxx in cxx_suffixes: +		act = SCons.Action.Action('$QT4_MOCFROMCXXCOM', cmdstr = '$QT4_MOCFROMCXXCOMSTR') +		mocBld.add_action(cxx, act) +		mocBld.prefix[cxx] = '$QT4_MOCCXXPREFIX' +		mocBld.suffix[cxx] = '$QT4_MOCCXXSUFFIX' +	env['BUILDERS']['Moc4'] = mocBld + +	# er... no idea what that was for +	static_obj, shared_obj = SCons.Tool.createObjBuilders(env) +	static_obj.src_builder.append('Uic4') +	shared_obj.src_builder.append('Uic4') + +	# We use the emitters of Program / StaticLibrary / SharedLibrary +	# to scan for moc'able files +	# We can't refer to the builders directly, we have to fetch them +	# as Environment attributes because that sets them up to be called +	# correctly later by our emitter. +	env.AppendUnique(PROGEMITTER =[AutomocStatic], +					 SHLIBEMITTER=[AutomocShared], +					 LIBEMITTER  =[AutomocStatic], +					 # Of course, we need to link against the qt libraries +					 LIBPATH=["$QT4_LIBPATH"], +					 LIBS=['$QT4_LIB']) + +	# TODO: Does dbusxml2cpp need an adapter +	env.AddMethod(enable_modules, "EnableQt4Modules") + +def enable_modules(self, modules, debug=False, crosscompiling=False) : +	import sys + +	validModules = [ +		'QtCore', +		'QtGui', +		'QtOpenGL', +		'Qt3Support', +		'QtAssistant', +		'QtScript', +		'QtDBus', +		'QtSql', +		# The next modules have not been tested yet so, please +		# maybe they require additional work on non Linux platforms +		'QtNetwork', +		'QtSvg', +		'QtTest', +		'QtXml', +		'QtXmlPatterns', +		'QtUiTools', +		'QtDesigner', +		'QtDesignerComponents', +		'QtWebKit', +		'QtHelp', +		'QtScript', +		] +	staticModules = [ +		'QtUiTools', +	] +	invalidModules=[] +	for module in modules: +		if module not in validModules : +			invalidModules.append(module) +	if invalidModules : +		raise Exception("Modules %s are not Qt4 modules. Valid Qt4 modules are: %s"% ( +			str(invalidModules),str(validModules))) + +	moduleDefines = { +		'QtScript'	 : ['QT_SCRIPT_LIB'], +		'QtSvg'			 : ['QT_SVG_LIB'], +		'Qt3Support' : ['QT_QT3SUPPORT_LIB','QT3_SUPPORT'], +		'QtSql'			 : ['QT_SQL_LIB'], +		'QtXml'			 : ['QT_XML_LIB'], +		'QtOpenGL'	 : ['QT_OPENGL_LIB'], +		'QtGui'			 : ['QT_GUI_LIB'], +		'QtNetwork'  : ['QT_NETWORK_LIB'], +		'QtCore'		 : ['QT_CORE_LIB'], +	} +	for module in modules : +		try : self.AppendUnique(CPPDEFINES=moduleDefines[module]) +		except: pass +	debugSuffix = '' + +	if sys.platform in ["linux2"] and not crosscompiling : +		if debug : debugSuffix = '_debug' +		self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include", "phonon")]) +		for module in modules : +			self.AppendUnique(LIBS=[module+debugSuffix]) +			self.AppendUnique(LIBPATH=[os.path.join("$QTDIR","lib")]) +			self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include")]) +			self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include",module)]) +		self["QT4_MOCCPPPATH"] = self["CPPPATH"] +		return + +	if sys.platform == "win32" or crosscompiling : +		if crosscompiling: +			transformedQtdir = transformToWinePath(self['QTDIR']) +			self['QT4_MOC'] = "QTDIR=%s %s"%( transformedQtdir, self['QT4_MOC']) +		self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include")]) +		try: modules.remove("QtDBus") +		except: pass +		if debug : debugSuffix = 'd' +		if "QtAssistant" in modules: +			self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","QtAssistant")]) +			modules.remove("QtAssistant") +			modules.append("QtAssistantClient") +		# FIXME: Phonon Hack +		self.AppendUnique(LIBS=['phonon4'+debugSuffix]) +		self.AppendUnique(LIBS=[lib+'4'+debugSuffix for lib in modules if lib not in staticModules]) +		self.PrependUnique(LIBS=[lib+debugSuffix for lib in modules if lib in staticModules]) +		if 'QtOpenGL' in modules: +			self.AppendUnique(LIBS=['opengl32']) +		self.AppendUnique(CPPPATH=[ '$QTDIR/include/']) +		self.AppendUnique(CPPPATH=[ '$QTDIR/include/'+module for module in modules]) +		if crosscompiling : +			self["QT4_MOCCPPPATH"] = [ +				path.replace('$QTDIR', transformedQtdir) +					for path in self['CPPPATH'] ] +		else : +			self["QT4_MOCCPPPATH"] = self["CPPPATH"] +		self.AppendUnique(LIBPATH=[os.path.join('$QTDIR','lib')]) +		return + +	if sys.platform=="darwin" : +		if debug : debugSuffix = 'd' + +		if len(self["QTDIR"]) > 0 : +			self.AppendUnique(LIBPATH=[os.path.join('$QTDIR','lib')]) +			self.AppendUnique(LINKFLAGS="-F$QTDIR/lib") +			self.AppendUnique(CPPFLAGS="-F$QTDIR/lib") +			self.AppendUnique(LINKFLAGS="-L$QTDIR/lib") #TODO clean! + +		# FIXME: Phonon Hack +		self.Append(LINKFLAGS=['-framework', "phonon"]) + +		for module in modules : +			if module in staticModules : +				self.AppendUnique(LIBS=[module+debugSuffix]) # TODO: Add the debug suffix +				self.AppendUnique(LIBPATH=[os.path.join("$QTDIR","lib")]) +			else : +				if len(self["QTDIR"]) > 0 : +					self.Append(CPPFLAGS = ["-I" + os.path.join("$QTDIR", "lib", module + ".framework", "Versions", "4", "Headers")]) +				else : +					self.Append(CPPFLAGS = ["-I" + os.path.join("/Library/Frameworks", module + ".framework", "Versions", "4", "Headers")]) +				self.Append(LINKFLAGS=['-framework', module]) +		if 'QtOpenGL' in modules: +			self.AppendUnique(LINKFLAGS="-F/System/Library/Frameworks") +			self.Append(LINKFLAGS=['-framework', 'AGL']) #TODO ughly kludge to avoid quotes +			self.Append(LINKFLAGS=['-framework', 'OpenGL']) +		self["QT4_MOCCPPPATH"] = self["CPPPATH"] + +def exists(env): +	return _detect(env) diff --git a/BuildTools/SCons/Version.py b/BuildTools/SCons/Version.py new file mode 100644 index 0000000..02edcc9 --- /dev/null +++ b/BuildTools/SCons/Version.py @@ -0,0 +1,15 @@ +import subprocess, os, datetime + +def getGitBuildVersion() : +  p = subprocess.Popen("git rev-parse HEAD", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=(os.name != "nt")) +  gitVersion = p.stdout.read().rstrip()[0:7] +  p.stdin.close() +  return gitVersion if p.wait() == 0 else None + +def getBuildVersion(version = None) : +  if version : +    return version +  gitVersion = getGitBuildVersion()  +  if gitVersion : +    return gitVersion +  return datetime.date.today().strftime("%Y%m%d") diff --git a/BuildTools/package_debian.sh b/BuildTools/package_debian.sh new file mode 100755 index 0000000..3d01243 --- /dev/null +++ b/BuildTools/package_debian.sh @@ -0,0 +1,10 @@ +VERSION=1.0 +PACKAGE=swift-$VERSION + +rm -rf $PACKAGE +git archive --format=tar --prefix=$PACKAGE/ HEAD | tar x +cp -r Swift/Packaging/Debian $PACKAGE/debian +pushd $PACKAGE +SWIFT_VERSION=$VERSION dpkg-buildpackage -rfakeroot +popd +rm -rf $PACKAGE  | 
 Swift